【问题标题】:make perl shout when trying to access undefined hash key尝试访问未定义的哈希键时让 perl 大喊大叫
【发布时间】:2011-03-23 19:25:19
【问题描述】:

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

最好, 戴夫

【问题讨论】:

  • 你不是要检查一个键是否是defined,而是检查它是否是exists本身没有未定义的哈希键。
  • @pilcrow 感谢您的更正。

标签: perl hash


【解决方案1】:

这可能最好使用绑定哈希来完成。绑定变量允许您定义变量的低级操作的实现。在这种情况下,我们需要一个特殊的 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,它提供了Tie::StdHash。将 @ISA 设置为 Tie::StdHash 为我们的新包提供了与普通哈希相同的 tie 方法。 http://perldoc.perl.org/perltie.html

上概述了每种 tie 方法

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

【讨论】:

  • 非常酷!你能解释一下 FETCH 部分吗?这是保留字吗?
  • 绑定变量提供了一组方法供您覆盖,允许您指定它们的行为。有关所有详细信息,请参阅 perltie:perldoc.perl.org/perltie.html
【解决方案2】:

使用 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.

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

【讨论】:

  • 谢谢,这很好,但我想知道是否有更适合我需要的东西。我希望每当我尝试访问未定义的键时都会生成错误,除非访问是分配。我的哈希是动态的——我一直在添加密钥和获取密钥——所以使用 Hash::Util 将使我不断锁定和解锁,我不妨检查密钥是否已定义。
  • @David B:那么您可能想要使用绑定哈希,正如 Eric Strom 所建议的那样。虽然我想知道你到底在用你得到的值做什么?假设您启用了警告,许多操作应该已经对未定义的值发出警告。
【解决方案3】:

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

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

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

【讨论】:

    猜你喜欢
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 2015-04-28
    • 2013-06-06
    • 1970-01-01
    • 2019-04-10
    相关资源
    最近更新 更多