2012-11-07 29 views
2
nonvivificate

比方說,我有一個Perl腳本,它:如何在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; 

但我的輸出autocreates「C」,這是我不想要的。

defined a 
undef b 
undef c 
$VAR1 = { 
     'c' => {}, 
     'a' => { 
       'aa' => 'b' 
      }, 
     'b' => {} 
    }; 

此外,我的發行版不允許我禁用autovivification。有沒有辦法讓一個子程序檢查每個級別?

回答

1

下面是一個簡單的函數,它檢查每個級別的存在,並停止沒有autovivifying中間級別。原型是沒有必要的;它使其行爲(有點)像內置defined。該版本僅適用於嵌套散列(除了祝福的散列和看起來像散列的重載對象之外)。

sub noVivDefined([email protected]) { 
    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' 
+0

Personnally,I' d返回對元素的引用,這樣,你不需要再次潛水來處理你發現的值定義。 '我的$ ref =潛水\%h,@k; if($ ref && defined $$ ref){say $$ ref; } else {say「[undef]」}' – ikegami

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}) { 
    ... 
} 
+0

我將如何做到這一點編程?如果我調用了'noVivDefined($ hash - > {$ _} - > {aa};' –

+0

正確的話,我的發行版不能'autovivification;' –

+1

@EricFossum:你可以調用函數noVivDefined $ hashref,@keys)''它會遍歷關鍵字並在每個級別執行'defined'檢查。 –

3

什麼是錯的:

if (exists $hash->{$_} and defined $hash->{$_}->{aa}) 
+0

這不是非常程序化的......如果我想寫出所有東西,我只是不使用循環。 –

+0

在整個示例中添加** one **表達式(〜24個字符)會使其「不務實」,並導致「將所有內容寫出來」和「破壞循環的目的」?這是荒謬的誇張。提供一個實際顯示問題的實例,然後... –