3

我正在寻找一种更好的方法来首先“测试”哈希键在使用之前是否存在。我目前正在编写一个事件日志解析器,它将十六进制数字解码为字符串。由于我无法确定我的解码表是否包含十六进制数字,我首先需要检查密钥是否存在于哈希中,然后再将值分配给新变量。所以我经常做的是:

if ($MEL[$i]{type} eq '5024') {
  $MEL[$i]{decoded_inline} = $decode_hash{checkpoint}{"$MEL[$i]{raw}[128]"}
    if exists ($decode_hash{checkpoint}{"$MEL[$i]{raw}[128]"})
}

我不喜欢的是该表达式$decode_hash{checkpoint}{"$MEL[$i]{raw}[128]"}在我的代码中出现了两次。上面的行有更好或更短的版本吗?

4

3 回答 3

4

我怀疑这是否称得上“不错”,但我认为它正在实现不两次引用该表达式的目标。我不确定这是否值得这种痛苦,请注意:

my $foo = $decode_hash{checkpoint}; 
my $bar = $MEL[$i]{raw}[128]; 
if ($MEL[$i]{type} eq '5024') { 
  $MEL[$i]{decoded_inline} = $foo->{$bar} 
    if exists ( $foo->{$bar} ); 
} 
于 2012-11-17T12:08:38.410 回答
2

是的,有一种更简单的方法。您知道您只能将引用存储在数组或哈希中,对吗?嗯,这有一个很好的副作用。您可以引用深度散列或数组槽,然后将它们视为标量引用。不幸的副作用是它会自动激活该插槽,但是如果您总是要分配给该插槽,并且只想先进行一些检查,那么避免一遍又一遍地输入内容并不是一个坏方法——因为以及重复索引结构。

my $ref = \$decode_hash{checkpoint}{"$MEL[$i]{raw}[128]"};
unless ( defined( $$ref )) { 
    ...
    $$ref = {};
    ...
}
于 2012-11-18T05:00:31.310 回答
1

只要现有的哈希元素不能有未定义的值,我就会写这个

if ($MEL[$i]{type} eq '5024') {
  my $value = $decode_hash{checkpoint}{$MEL[$i]{raw}[128]};
  $MEL[$i]{decoded_inline} = $value if defined $value;
}

(请注意,您不应该在哈希键周围加上双引号。)

于 2012-11-17T15:55:21.150 回答