你在混合词法和包变量。如果你的程序有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
不再存在。
如果你有在你的程序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