在尝试访问未定义的哈希键时使perl大喊

时间:2010-08-01 07:28:14

标签: perl hash

我认为标题是不言自明的。很多时候我有小错别字,在尝试访问未定义的哈希键时会得到意想不到的结果。我知道每次访问哈希键之前我都可以添加一些defined检查,但我想知道是否有更清晰的方法来警告这些情况....

最佳, 戴夫

3 个答案:

答案 0 :(得分:14)

这可能最好使用绑定哈希。绑定变量允许您定义变量的低级操作的实现。在这种情况下,我们需要一个特殊的fetch方法,在访问不存在的键时会死掉:

use warnings;
use strict;

{package Safe::Hash;
        require Tie::Hash;
        our @ISA = 'Tie::StdHash';
        use Carp;

        sub FETCH { 
                exists $_[0]{$_[1]} or croak "no key $_[1]";
                $_[0]{$_[1]}
        }
}

tie my %safe => 'Safe::Hash';

$safe{a} = 5;  # ok

print $safe{a}, "\n";  # ok

$safe{b} = 10; # ok 

print $safe{bb}, "\n";  # dies

在上面Safe::Hash的实施中,我首先加载提供Tie::Hash的{​​{1}}。将Tie::StdHash设置为@ISA为我们的新包提供了与正常哈希行为相同的tie方法。每个联系方法都在http://perldoc.perl.org/perltie.html

上列出

在这种情况下,唯一要覆盖的方法是Tie::StdHash,它传递对隐藏绑定对象(在本例中为hashref)的引用,以及要使用的密钥。它检查插槽是否存在,并返回它或抛出错误

答案 1 :(得分:8)

使用Hash :: Util:

use Hash::Util "lock_keys";
my %hash = (foo => 42, bar => 23);
lock_keys(%hash);
print $hash{foo};
print $hash{baz};
print $hash{bar};

输出:

42
Attempt to access disallowed key 'baz' in a restricted hash at foo line 5.

还有其他功能可以指定允许哪些键,而不仅仅是默认那些已经存在的键。

答案 2 :(得分:4)

您可以为此编写一个简单的函数:

sub get {
    my ($hash, $key) = @_;
    die "No such key: $key" unless exists $hash->{$key};
    return $hash->{$key};
}

my %hash = (...);    
my $val = get(\%hash, "mykey");