参数的意外自动生成
Unexpected autovivification of arguments
显然我对 no autovivification pragma 的理解不完善,因为以下脚本的 not-dying-on-line-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->{bar}
作为参数提供给 sub 时,为什么 $foo
自动生成,即使 no autovivification
有效?
在子例程调用中,函数的参数在 @_
中使用别名,因此必须可以修改它们。这提供了一个 lvalue 上下文,它将触发自动生成。
当我们查看您在 autovivification 中使用的功能的描述时,它们包括:
'fetch'
-- "rvalue dereferencing expressions"
'exists'
-- "dereferencing expressions that are parts of an exists"
'delete'
-- "dereferencing expressions that are parts of a delete"
None 其中处理左值(warn
)。
要停止子程序调用中的自动生成,您还需要添加 store
Turns off autovivification for lvalue dereferencing expressions, such as : [...]
文档继续提供示例,包括子例程调用。
当我将它添加到您的代码中时,
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.
显然我对 no autovivification pragma 的理解不完善,因为以下脚本的 not-dying-on-line-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->{bar}
作为参数提供给 sub 时,为什么 $foo
自动生成,即使 no autovivification
有效?
在子例程调用中,函数的参数在 @_
中使用别名,因此必须可以修改它们。这提供了一个 lvalue 上下文,它将触发自动生成。
当我们查看您在 autovivification 中使用的功能的描述时,它们包括:
'fetch'
-- "rvalue dereferencing expressions"'exists'
-- "dereferencing expressions that are parts of an exists"'delete'
-- "dereferencing expressions that are parts of a delete"
None 其中处理左值(warn
)。
要停止子程序调用中的自动生成,您还需要添加 store
Turns off autovivification for lvalue dereferencing expressions, such as : [...]
文档继续提供示例,包括子例程调用。
当我将它添加到您的代码中时,
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.