заставить perl кричать при попытке получить доступ к неопределенному ключу хеша - PullRequest
8 голосов
/ 01 августа 2010

Я думаю, что название говорит само за себя. Много раз у меня были небольшие опечатки, и я получал неожиданные результаты при попытке получить доступ к неопределенным хеш-ключам. Я знаю, что могу добавлять некоторую проверку defined перед каждым обращением к хеш-ключу, но мне интересно, есть ли какой-нибудь более чистый способ предостеречь от таких случаев ...

Лучший, Dave

Ответы [ 3 ]

15 голосов
/ 01 августа 2010

Это, вероятно, лучше всего сделать с привязанным хешем. Связанные переменные позволяют определить реализацию низкоуровневых операций с переменной. В этом случае нам нужен специальный метод выборки, который умирает при доступе к несуществующим ключам:

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 предоставляет нашему новому пакету методы связи, которые ведут себя так же, как обычные хеши. Каждый из методов связи описан на http://perldoc.perl.org/perltie.html

В этом случае единственный метод для переопределения - это FETCH, которому передается ссылка на скрытый связанный объект (в данном случае хэш-ссылка) и ключ для использования. Он проверяет, существует ли слот, и либо возвращает его, либо выдает ошибку

8 голосов
/ 01 августа 2010

Использовать 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};

output:

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

Существуют другие функции, которые позволяют указать, какие ключи разрешать, а не просто использовать по умолчанию то, что уже есть.

4 голосов
/ 01 августа 2010

Вы можете написать простую функцию для этого:

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

my %hash = (...);    
my $val = get(\%hash, "mykey");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...