实际上,当我尝试初始化Perl Hash(ref)并尝试立即通过autovivication分配它时,我发现了一种奇怪的行为。这是一个简短的Codesnippet,使它更清晰:
use Data::Dumper;
my $hash->{$_} = 'abc' foreach (1..4);
print Dumper $hash;
打印:
$VAR1 = undef;
当我这样尝试时:
use Data::Dumper;
my $hash;
$hash->{$_} = 'abc' foreach (1..4);
print Dumper $hash;
我得到了
$VAR1 = {
'4' => 'abc',
'1' => 'abc',
'3' => 'abc',
'2' => 'abc'
};
这是我的预期。所以问题是$hash
的(多次)初始化。
我知道,使用map
的方式是更好的解决方案:
use Data::Dumper;
my $hash = { map { $_ => 'abc' } (1..4) };
print Dumper $hash;
现在我的问题: 为什么初始化和分配的方式会失败?
答案 0 :(得分:8)
阅读Statement Modifiers的perlsyn - Perl Syntax部分末尾附近的注释:
注意:my,state或我们使用语句修饰符条件或循环结构修改的行为(例如,我的$ x if ...)是未定义的。 my变量的值可以是undef,任何先前分配的值,或者可能是其他任何值。不要依赖它。 perl的未来版本可能会与您尝试使用的perl版本有所不同。这里是龙。
答案 1 :(得分:1)
您希望这可行吗?
foreach ( 1 .. 4 ){
my $hash->{$_} = 'abc';
}
PBP表示您不应使用除if
之外的任何语句修饰符,然后才能修改last
,next
或redo
。
答案 2 :(得分:0)
如果您比较以下两个输出,应该很容易理解为什么您在$hash
中没有任何内容。循环之前没有padsv
,因此循环获得自己的同名变量(填充中的索引相同)。
这意味着您实际上有名为$hash
的 2或5 变量。 (我不确定循环是否保持相同的变量,或者每次是否获得新变量。)
perl -MO=Terse -e'my $hash->{$_} = "abc" for 1..4;print $hash'
LISTOP (0x1e7ff90) leave [1]
OP (0x1f8ace0) enter
COP (0x1e35e60) nextstate
BINOP (0x1e34aa0) leaveloop
LOOP (0x1e35dc0) enteriter
OP (0x1e35bd0) null [3]
UNOP (0x1e36050) null [146]
OP (0x1e27870) pushmark
SVOP (0x1e35c90) const [7] IV (0x1e2da60) 1
SVOP (0x1e35c20) const [8] IV (0x1e2dad8) 4
PADOP (0x1e89160) gv GV (0x1e0e7c0) *_
UNOP (0x1e35cd0) null
LOGOP (0x1e35f00) and
OP (0x1e35d90) iter
LISTOP (0x1e34960) lineseq
BINOP (0x1e34a00) sassign
SVOP (0x1e34a60) const [9] PV (0x1e2db68) "abc"
BINOP (0x1e35d10) helem
UNOP (0x1e35d50) rv2hv [3]
OP (0x1e34930) padsv [1] # <-----
UNOP (0x1e35e20) null [15]
PADOP (0x1e35fe0) gvsv GV (0x1e0e7c0) *_
OP (0x1fa9ad0) unstack
COP (0x1e26830) nextstate
LISTOP (0x1fb8e30) print
OP (0x1fa9a10) pushmark
OP (0x1e26800) padsv [1] # <-----
perl -MO=Terse -e'my $hash;$hash->{$_} = "abc" for 1..4;print $hash'
LISTOP (0xb33fe0) leave [1]
OP (0xc88c00) enter
COP (0xb32a40) nextstate
OP (0xb32930) padsv [1] # <-----
COP (0xb33f40) nextstate
BINOP (0xb33cd0) leaveloop
LOOP (0xb33e60) enteriter
OP (0xb33d90) null [3]
UNOP (0xb87160) null [146]
OP (0xb25870) pushmark
SVOP (0xb33c20) const [7] IV (0xb2ba60) 1
SVOP (0xb32aa0) const [8] IV (0xb2bad8) 4
PADOP (0xb7df90) gv GV (0xb0c7c0) *_
UNOP (0xb33f00) null
LOGOP (0xb32960) and
OP (0xca7ad0) iter
LISTOP (0xb34050) lineseq
BINOP (0xb33c90) sassign
SVOP (0xb33de0) const [9] PV (0xb2bb68) "abc"
BINOP (0xb32a00) helem
UNOP (0xb33d10) rv2hv [3]
OP (0xb33bd0) padsv [1] # <-----
UNOP (0xb33d50) null [15]
PADOP (0xb33e20) gvsv GV (0xb0c7c0) *_
OP (0xca7aa0) unstack
COP (0xb24830) nextstate
LISTOP (0xcb6e30) print
OP (0xc88ce0) pushmark
OP (0xb24800) padsv [1] # <-----