是否可以在Perl中提供一个钩子以确保没有Hash密钥查找失败?
示例:
use strict;
use warnings;
my %hash_example = ( "a"=>"apple", "b"=>"ball" );
print $hash_example{"a"}; # Goes Fine.
print $hash_example{"c"}; # Throws Warning ( "Use of uninitialized value " ).
每当发生哈希查找时,可以调用某个子例程,它可以提供默认值。
我的意思是,任何哈希查找都应该调用一个sub(比如“get_hash_value (hash_ref, key)
”)并将哈希和密钥传递给它。这样一个子样本如下所示:
sub get_hash_value {
my $hash_ref = shift;
my $key = shift;
if ( exists $hash_ref->{$key} ) { # For Normal Lookup.
return $hash_ref->{$key};
}
else {
# This is the interesting place where we could provide our own values.
return "custom_value_based_on_certain_conditions"; # Some value
}
}
另一个结果是能够改变针对密钥返回的值。我们将能够返回与该键存储的实际值不同的值(在该哈希值中)。
可能没有一个有效的用例,但我很感兴趣,并希望了解Perl是否支持这些内容。
答案 0 :(得分:3)
正如Сухой27在评论中所说,这很好用:
my %hash_example = ( "a"=>"apple", "b"=>"ball" );
print $hash_example{"a"};
print $hash_example{"c"} // "custom_value_based_on_certain_conditions";
答案 1 :(得分:2)
我建议尝试改变散列查找“工作”的方式是一个非常糟糕的想法,作为创建难以维护的代码的好方法。
但是我会建议您查看创建对象而不是哈希。它们基本上是相同的,但是一个对象包含代码,并且有一个期望,对象中的代码是“做它自己的事情”。
所以在基本层面:
#!/usr/bin/env perl
use strict;
use warnings;
package Hash_Ob;
sub new {
my ($class) = @_;
my $self = {};
bless( $self, $class );
return $self;
}
sub get_value {
my ( $self, $valuename ) = @_;
if ( $self->{$valuename} ) {
return $self->{$valuename};
}
else {
#generate your own value here!
$self->{$valuename} = 42;
return $self->{$valuename};
}
}
1;
然后使用以下方式“呼叫”:
#!/usr/bin/env perl
use strict;
use warnings;
use Hash_Ob;
my $magic_hash = Hash_Ob -> new();
print $magic_hash -> get_value('new_value');
这避免了改变“众所周知”机制实际工作方式的问题,因此未来的维护程序员不会诅咒你的名字。
答案 2 :(得分:2)
那么也许你想使用绑定哈希。绑定是一种改变内置数据类型行为的机制。有关血腥的详细信息,请参阅perltie
。
{
package HashWithDefault;
use Tie::StdHash;
our @ISA = qw(Tie::StdHash); # inherit STORE, FIRST, NEXT, etc.
sub TIEHASH {
my ($pkg,$default_val) = @_;
return bless { __default_val__ => $default_val}, $pkg;
}
sub FETCH {
my ($self,$key) = @_;
exists $self->{$key} ? $self->{$key} : $self->{__default_val__};
}
sub CLEAR { # don't clear the default val
my $self = shift;
%$self = ( __default_val__ => $self->{__default_val__} );
}
}
tie my %hash, 'HashWithDefault', "42";
%hash = (foo => 123, bar => 456);
print $hash{foo}; # 123
print $hash{quux}; # 42