Неожиданная автовизуализация аргументов

По-видимому, мое понимание no autovivification прагмы несовершенно, так как поведение не-умирающих на линии-19 следующего script чрезвычайно удивительно для меня.

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;
}

Запуск script вызывает:

Reference was vivified at test.pl line 8.

Вопрос: почему autovivified $foo, когда $foo->{bar} предоставляется в качестве аргумента для sub, даже если no autovivification действует?

Ответ 1

В вызове подпрограммы аргументы функции сглажены в @_, поэтому их необходимо изменить. Это обеспечивает контекст lvalue, что приведет к автовивитации.

Когда мы просматриваем описания функций, которые вы используете в autovivification, они охватывают:

  • 'fetch' - "выражения разыменования rvalue"
  • 'exists' - "выражения разыменования, являющиеся частями существующего"
  • 'delete' - "выражения разыменования, которые являются частями удаления"

Ни одно из них не связано с lvalues ​​(также не имеет значения warn).

Чтобы остановить автовивитацию в вызовах подпрограмм, вам нужно добавить store

Отключает автовивитацию для выражений разыменования lvalue, таких как: [...]

где документы идут с примерами, включая вызовы подпрограмм.

Когда я добавлю его в свой код,

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.