Хранение '1' в сет-хэше считается опасным
Я знаю, используя Считается вредным считается вредным , но это плохо; почти так же плохо, как безудержное использование goto
.
Хорошо, я об этом говорил в нескольких комментариях, но, думаю, мне нужен полный ответ, чтобы продемонстрировать проблему.
Допустим, у нас есть процесс-демон, который обеспечивает внутренний контроль запасов для магазина, который продает виджеты.
my @items = qw(
widget
thingy
whozit
whatsit
);
my @items_in_stock = qw(
widget
thingy
);
my %in_stock;
my @in_stock(@items_in_stock) = (1) x @items_in_stock; #initialize all keys to 1
sub Process_Request {
my $request = shift;
if( $request eq REORDER ) {
Reorder_Items(\@items, \%in_stock);
}
else {
Error_Response( ILLEGAL_REQUEST );
}
}
sub Reorder_Items{
my $items = shift;
my $in_stock = shift;
# Order items we do not have in-stock.
for my $item ( @$items ) {
Reorder_Item( $item )
if not exists $in_stock->{$item};
}
}
Инструмент отличный, он автоматически сохраняет товары на складе. Очень хорошо. Теперь босс просит автоматически сгенерированные каталоги товаров на складе. Поэтому мы модифицируем Process_Request()
и добавляем генерацию каталога.
sub Process_Request {
my $request = shift;
if( $request eq REORDER ) {
Reorder_Items(\@items, \%in_stock);
}
if( $request eq CATALOG ) {
Build_Catalog(\@items, \%in_stock);
}
else {
Error_Response( ILLEGAL_REQUEST );
}
}
sub Build_Catalog {
my $items = shift;
my $in_stock = shift;
my $catalog_response = '';
foreach my $item ( @$items ) {
$catalog_response .= Catalog_Item($item)
if $in_stock->{$item};
}
return $catalog_response;
}
В тестировании Build_Catalog () работает нормально. Ура, мы живем с приложением.
К сожалению. По какой-то причине ничего не заказывается, у компании нет на складе всего .
Подпрограмма Build_Catalog()
добавляет ключи к %in_stock
, поэтому Reorder_Items()
теперь видит все как в наличии и никогда не делает заказ.
Использование Hash :: Util lock_hash
может помочь предотвратить случайное изменение хеша. Если бы мы заблокировали %in_stock
перед вызовом 'Build_Catalog ()', мы получили бы фатальную ошибку и никогда бы не сработали с ошибкой.
Таким образом, лучше всего проверить наличие ключей, а не истинность ваших значений set-hash. Если вы используете в качестве обозначения наличие, не устанавливайте значения «1», потому что это замаскирует ошибки и затруднит их отслеживание. Использование lock_hash
может помочь решить эти проблемы.
Если вы должны проверить правильность значений, сделайте это в в каждом случае.