比较使用perl -w -Mstrict:
# case Alpha print $c;
…
# case Bravo if (0) { my $c = 1; } print $c;
…
# case Charlie my $c = 1 if 0; print $c;
Alpha和Bravo都抱怨没有显式包名称的全局符号,这是预期的.但是查理没有给出相同的警告,只有这个价值是未初始化的,这闻起来很像:
# case Delta my $c; print $c;
在引擎盖下究竟发生了什么? (即使这样做不应该写为生产代码)
解决方法
您可以将我的声明视为在编译时和运行时都有动作.在编译时,我的一个声明告诉编译器记下一个符号是否存在,直到当前词法范围结束.该声明中的符号的转让或其他使用将在运行时进行.
所以你的例子
my $c = 1 if 0;
就好像
my $c; # compile-time declaration,initialized to undef $c = 1 if 0; # runtime -- as written has no effect
请注意,此编译时/运行时区别允许您编写这样的代码.
my $DEBUG; # lexical scope variable declared at compile-time BEGIN { $DEBUG = $ENV{MY_DEBUG}; # statement executed at compile-time };
现在可以猜到这个程序的输出是什么?
my $c = 3; BEGIN { print "\$c is $c\n"; $c = 4; } print "\$c is $c\n";