假设我有一个Perl脚本:
my $hash = {};
$hash->{'a'} = {aa => 'b'};
$hash->{'b'} = undef;
for (qw(a b c)) {
if(defined $hash->{$_}->{aa})
{
say "defined $_";
}
else
{
say "undef $_";
}
}
print Dumper $hash;
但我的输出会自动创建'c',我不想要。
defined a
undef b
undef c
$VAR1 = {
'c' => {},
'a' => {
'aa' => 'b'
},
'b' => {}
};
此外,我的发行版不允许我禁用自动审核。有没有办法制作一个检查每个级别的子程序?
答案 0 :(得分:11)
在所需范围内呼叫no autovivification
:
for (qw(a b c)) {
no autovivification;
if(defined $hash->{$_}->{aa})
{
say "defined $_";
}
else
{
say "undef $_";
}
}
如果autovivification
编译指示不可用,通常的习惯用法是在更深层次的检查之前测试是否存在顶级哈希:
if ($hash && $hash->{$_} && defined($hash->{$_}->{aa}) {
...
}
答案 1 :(得分:3)
有什么问题:
if (exists $hash->{$_} and defined $hash->{$_}->{aa})
答案 2 :(得分:1)
这是一个简单的函数,它检查每个级别是否存在并停止而不自动生成中间级别。原型不是必需的;它使它像内置的defined
一样行事(有点像)。此版本仅适用于嵌套哈希(除了有福的哈希和看似哈希的重载对象)。
sub noVivDefined(+@) {
my ($x, @keys) = @_;
foreach my $k (@keys) {
return unless ref $x eq 'HASH';
return unless exists $x->{$k};
$x = $x->{$k};
}
return defined $x;
}
my %h = (
a => { b => 1 },
b => { b => 0 },
c => { b => undef },
d => { c => 1 },
);
say noVivDefined %h, qw(a b); # prints '1'
say noVivDefined %h, qw(a b c); # prints ''
say noVivDefined %h, qw(x y z); # prints ''
say noVivDefined %h, qw(b b); # prints '1'
say noVivDefined %h, qw(c b); # prints ''
say noVivDefined %h, qw(d b); # prints ''
say noVivDefined \%h, qw(a b); # prints '1'