Я думаю, что заголовок очевиден. Много раз у меня есть маленькие опечатки, и я получаю неожиданные результаты при попытке получить доступ к неопределенным ключам хеша. Я знаю, что могу добавить некоторых defined
проверьте перед каждым разом, когда я получаю доступ к ключу хеша, но интересно, существует ли какой-либо более чистый способ предостеречь от таких случаев....
Лучше всего, Dave
Вероятно, это лучше всего сделать с помощью связанного хэша. Связанные переменные позволяют определить реализацию низкоуровневых операций с переменной. В данном случае нам нужен специальный метод выборки, который умирает при обращении к несуществующим ключам:
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, которые ведут себя так же, как и обычные хэши. Каждый из методов tie описан на http://perldoc.perl.org/perltie.html
В данном случае единственным методом, который нужно переопределить, является FETCH
, которому передается ссылка на скрытый связанный объект (в данном случае хэш-реф) и ключ, который нужно использовать. Она проверяет, существует ли слот, и либо возвращает его, либо выдает ошибку
Использовать 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.
Существуют и другие функции, которые позволяют указать, какие ключи разрешить, а не просто использовать по умолчанию то, что уже есть.
Вы можете написать простую функцию для этого :
sub get {
my ($hash, $key) = @_;
die "No such key: $key" unless exists $hash->{$key};
return $hash->{$key};
}
my %hash = (...);
my $val = get(\%hash, "mykey");