0

当不存在的键分配给变量时,Perl 是否真正自动激活键?

我有这个代码:

my $variable = $self->{database}->{'my_key'}[0];

该变量$self->{database}->{'my_key'}[0]在我的哈希中未定义,但如果我在分配后打印一个 Dumper,我很惊讶它my_key被创建了。

我知道这种情况的功能:

use Data::Dumper;

my $array;

$array->[3] = 'Buster';  # autovivification
print Dumper( $array );

这会给我结果:

$VAR1 = [ undef, undef, undef, 'Buster' ];

但从没想过会以相反的方式工作,其中 : my $weird_autovivification = $array->[3]; 也会活跃起来$array->[3]

4

2 回答 2

10

但从没想过会以相反的方式工作,其中 : my $weird_autovivification = $array->[3];也会变得活跃$array[3]

这不是它的工作原理。

$ perl -MData::Dumper -E'$foo=$array->[3]; say Dumper $array'
$VAR1 = [];

执行该代码已经变成$array了一个数组引用(以前,它是未定义的),但它没有设置$array->[3]任何东西。

如果我们添加另一个级别的查找,我们会得到稍微不同的行为:

$ perl -MData::Dumper -E'$foo=$array->[0][3]; say Dumper $array'
$VAR1 = [
          []
        ];

在这里,Perl 已创建$array->[0]并将其设置为对空数组的引用,但它并没有影响$array->[0][3].

通常,当您在复杂的数据结构中进行一系列查找时,Perl 将自动激活除了链中最后一个链接之外的所有链接。当您考虑它时,这很有意义。Perl 需要自动激活链中的一个链接,以便它可以检查下一个链接的存在。

于 2017-03-01T13:49:35.773 回答
7

当不存在的键分配给变量时,Perl 是否真正自动激活键?

Perl在取消引用时自动激活变量(包括数组元素和散列值)。

$foo->{bar}   [ $foo dereferenced as a hash   ]    ≡    ( $foo //= {} )->{bar}
$foo->[3]     [ $foo dereferenced as an array ]    ≡    ( $foo //= [] )->[3]
$$foo         [ $foo dereferenced as a scalar ]    ≡    ${ $foo //= do { my \$anon } }
etc

这意味着

$self->{database}->{'my_key'}[0]

自动激活

  • $self(如果未定义,则为哈希引用)
  • $self->{database}(如果未定义,则为哈希引用)
  • $self->{database}->{'my_key'}(如果未定义,则为数组 ref)

但不是

  • $self->{database}->{'my_key'}[0](因为它没有被取消引用)

但从没想过会以相反的方式工作,其中 :my $weird_autovivification = $array->[3];也会活跃起来$array->[3]

不完全的。它自动激活$array,变量被取消引用。$array->[3]由于没有取消引用,因此没有分配任何内容。


提示:autovivification pragma 可用于控制何时发生 autovivification。

于 2017-03-01T14:38:29.337 回答