参数的意外自动更新

时间:2017-03-08 09:57:06

标签: perl autovivification

显然,我对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}作为sub的参数提供时自动生成,即使no autovivification生效了?

1 个答案:

答案 0 :(得分:10)

在子程序调用中,函数的参数在@_中有别名,因此必须可以修改它们。这提供了一个左值上下文,它将触发自动生成。

当我们查看您在autovivification中使用的功能的说明时,它们涵盖:

  • 'fetch' - “rvalue dereferencing expressions”
  • 'exists' - “取消引用属于的部分的表达式
  • 'delete' - “取消引用属于删除
  • 的表达式

这些都不涉及左值(warn也没有。)

要在子程序调用中停止自动更新,您还需要添加store

  

关闭左值解除引用表达式的自动生成,例如:[...]

docs继续举例,包括子程序调用。

当我将其添加到您的代码中时,

no autovivification qw(fetch exists delete warn store);
# ...

我得到了

Reference was vivified at noautoviv.pl line 8.
Reference was vivified at noautoviv.pl line 16.
Died at noautoviv.pl line 19.