Perl在分配时自动生效

Joh*_*Doe 0 perl autovivification

当未显示的密钥分配给变量时,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 );
Run Code Online (Sandbox Code Playgroud)

这会给我结果:

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

但从来没有期望在其他方面工作,在哪里: my $weird_autovivification = $array->[3]; 也将生存$array->[3].

Dav*_*oss 10

但从来没有期望在其他方面工作,在哪里: my $weird_autovivification = $array->[3];也将vivificate $array[3].

这不是它的工作原理.

$ perl -MData::Dumper -E'$foo=$array->[3]; say Dumper $array'
$VAR1 = [];
Run Code Online (Sandbox Code Playgroud)

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

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

$ perl -MData::Dumper -E'$foo=$array->[0][3]; say Dumper $array'
$VAR1 = [
          []
        ];
Run Code Online (Sandbox Code Playgroud)

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

通常,当您在复杂的数据结构中查看一系列查找时,Perl将自动生成除链中最后一个链接之外的所有链接.当你考虑它时,这很有道理.Perl需要对链中的一个链接进行自动生成,以便它可以检查下一个链接是否存在.


ike*_*ami 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
Run Code Online (Sandbox Code Playgroud)

这意味着

$self->{database}->{'my_key'}[0]
Run Code Online (Sandbox Code Playgroud)

autovivifies

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

但不是

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

但从来没有期望在其他方面工作,在哪里:my $weird_autovivification = $array->[3];也将生存$array->[3].

不完全的.它自动生成$array,变量被解除引用.没有任何内容被分配,$array->[3]因为它没有被解除引用.


提示:autovivification pragma可用于控制何时发生自动修复.