Perl Hashref立即初始化并分配

时间:2013-08-05 12:00:08

标签: perl autovivification

实际上,当我尝试初始化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;

现在我的问题: 为什么初始化和分配的方式会失败?

3 个答案:

答案 0 :(得分:8)

阅读Statement Modifiersperlsyn - Perl Syntax部分末尾附近的注释:

  

注意:my,state或我们使用语句修饰符条件或循环结构修改的行为(例如,我的$ x if ...)是未定义的。 my变量的值可以是undef,任何先前分配的值,或者可能是其他任何值。不要依赖它。 perl的未来版本可能会与您尝试使用的perl版本有所不同。这里是龙。

答案 1 :(得分:1)

您希望这可行吗?

foreach ( 1 .. 4 ){
    my $hash->{$_} = 'abc';
}

PBP表示您不应使用除if之外的任何语句修饰符,然后才能修改lastnextredo

答案 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] # <-----
相关问题