【问题标题】:Perl auto-vivification on assignmentPerl 赋值时自动激活
【发布时间】:2017-03-01 12:53:22
【问题描述】:

当不存在的键分配给变量时,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]

【问题讨论】:

  • 你有什么问题?
  • @Borodin 更新了,我的错。这真的是 Perl 的行为吗?
  • 是的,它会创建具有自动激活功能的密钥。
  • @AbhiNickz 甚至在检查?例如。 if ( defined $self->{'unexisting_key'}) ..'因为那会很伤心..
  • @John Doe,关于“即使在检查时”,仅在尊重时。那 sn-p 取消引用 $self,所以 $self 我们被自动激活了。

标签: perl autovivification


【解决方案1】:

但从没想过会以相反的方式工作,其中: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 需要自动激活链中的一个链接,以便检查下一个链接是否存在。

【讨论】:

    【解决方案2】:

    当不存在的键被分配给变量时,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 可用于控制何时发生自动激活。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-24
      • 2015-08-26
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      相关资源
      最近更新 更多