我遇到了一些奇怪的行为,暗示我不了解Perl脚本执行和初始化顺序的一些基本内容。以下示例:
#!/usr/bin/env perl
use strict;
use warnings;
print &get_keys(), "\n";
use vars qw/%hello/; # same effect with 'my %hello = (...);'
%hello = ( a => 1, b => 2 );
sub get_keys
{
return join(', ', sort keys %hello);
}
打印一个空字符串。意味着尽管变量已经可见,但由于尚未达到赋值的状态,因此它没有值。 (使用标量而不是散列会触发有关未初始化变量的警告。)
这是预期的行为吗?
我也很高兴RTFM指针。
答案 0 :(得分:8)
来自perlsub:
my
同时具有编译时和 运行时效果。在编译时, 编译器会注意到它。该 这个的主要用处是 安静use strict 'vars'
....实际 初始化延迟到运行 但是,时间会被执行 适当的时间。
# At this point, %hello is a lexically scope variable (the my took effect
# at compile time), but it still has no keys.
print get_keys();
my %hello = ( a => 1, b => 2 );
# Now the hash has content.
print get_keys();
sub get_keys { join ' ', keys %hello, "\n" }
其他说明:(1)您应该使用my
或our
而不是use vars
。 (2)在正常情况下,不要使用前导符号调用函数:使用foo()
而不是&foo()
。
答案 1 :(得分:4)
是的,这是预期的行为。您在分配到get_keys()
之前致电%hello
,因此%hello
中get_keys()
为空。 (标量初始化为undef
,而默认情况下数组和散列设置为空。)
如果您希望立即初始化%hello
,请使用BEGIN块:
use vars qw/%hello/;
BEGIN {
%hello = ( a => 1, b => 2 );
}
请注意,如果您使用的是my
(或our
,那么这不起作用:
BEGIN {
my %hello = ( a => 1, b => 2 );
}
因为你必须在块之外声明变量,如下所示:
my %hello;
BEGIN {
%hello = ( a => 1, b => 2 );
}
答案 2 :(得分:3)
use vars
编译指示在编译时预先声明全局变量名。除非您为其指定任何值,否则该变量是未定义的。由于你在作业之前打印它,你理所当然地得到一个空字符串。
注意:对于当前包中的变量,提供的功能 通过这个pragma已被“我们的”声明取代,可用于 Perl v5.6.0或更高版本。请参阅perlfunc中的“our”。