显然,我对no autovivification编译指示的理解是不完善的,因为以下脚本的不死线19行为令我感到非常惊讶。

use 5.014;
use strict;
use warnings;
no autovivification qw(fetch exists delete warn);

{
  my $foo = undef;
  my $thing = $foo->{bar};

  # this does not die, as expected
  die if defined $foo;
}

{
  my $foo = undef;
  do_nothing( $foo->{bar} );

  # I would expect this to die, but it doesn't
  die unless defined $foo;
}

sub do_nothing {
  return undef;
}

运行脚本会产生:
Reference was vivified at test.pl line 8.

问题:即使$foo有效,当将$foo->{bar}作为子参数提供时,为什么no autovivification也能自动保存?

最佳答案

在子例程调用中,函数的参数在@_中是别名的,因此必须可以对其进行修改。这提供了一个左值上下文,它将触发自动生存。

当我们浏览您在autovivification中使用的功能的描述时,它们涵盖:

  • 'fetch'-“右值取消引用表达式”
  • 'exists'-“取消引用存在的一部分的表达式”
  • 'delete'-“取消引用属于删除的表达式”

  • 这些都不处理左值(warn也不处理)。

    要停止子程序调用中的自动执行,还需要添加store


    在这里文档将继续进行示例,包括子例程调用。

    当我将其添加到您的代码中时,
    no autovivification qw(fetch exists delete warn store);
    # ...
    

    我懂了

    引用在noautoviv.pl第8行中进行了活体检查。
    引用在noautoviv.pl第16行中进行了活体检查。
    死于noautoviv.pl第19行。

    10-08 00:03