你在混合詞法和包變量。如果你的程序有use strict
和use warnings
,這將是非常明顯的。
如果你沒有用my
聲明一個變量,Perl會認爲它是一個包變量。它將從程序的每個部分(在相同的命名空間中)可見。
如果你聲明變量爲my
,它將是詞彙。這意味着,它只有範圍內存在其創建。
my $foo = 1; #
#
if ($foo) { # #
my $bar = 2; # #
} # #
^^
| | scope that $foo exists in
| scope that $bar exists in
同樣的事情發生在這裏。
要設置包變量$::cmd
(與::
作爲main
命名空間)到"cat asdf"
的1st
子內部。然後您打電話2nd
分,這將進入else
分支。在這個範圍內,它將創建一個新的詞彙$cmd
。它只在程序的這一部分有效。然後傳遞給out_log()
,這可能會打印出來。之後,您將$::cmd
的"cat asdf"
值傳遞給out_log()
。此時新的$cmd
不再存在。
![code with freehand lines](https://i.stack.imgur.com/0Up3s.png)
如果你有在你的程序use strict
,該計劃將不會在所有的工作,因爲默認的包變量行爲是在這種情況下關閉的,所以你必須定義變量。
實際上,您不應該使用包變量操作,而是將參數傳遞給您的函數。
除此之外,還有一些其他的東西在你的程序中不是很好的做法。你應該使用3個參數open
和一個詞法文件句柄,並且檢查返回值open
。
功能的名稱不能以數字開頭,所以1st
和2nd
不是有效的名稱。最好是在他們所做或所代表的東西之後命名。這樣以後可以更輕鬆地閱讀您的程序。
一個完整的程序可能看起來像這樣。
use strict;
use warnings;
my ($code, $reg, $annotation); # these values come from somewhere...
run_cmd(compose_cmd(), $code, $reg, $annotation);
sub compose_cmd {
return "cat asdf";
}
sub run_cmd {
my ($cmd, $code, $reg, $annotation) = @_;
if ($code =~ /aa/) {
my $cmd = "$reg $annotation";
out_log($cmd);
}
else {
my $cmd = "$reg $annotation";
out_log($cmd);
}
out_log("$cmd");
open my $fh, '<', $cmd or die $!;
# do stuff with $fh ...
}
sub out_log {
print @_;
}
其實,subs不能以數字開頭。 – simbabque