这可能看起来很奇怪,但是如何在哈希本身“内部”引用哈希?这就是我想要做的事情:
我在末尾有一个带有子的散列哈希,比如:
my $h = { A => [...], B => [...], ..., EXPAND => sub { ... } };
。我希望实现EXPAND
以查看此哈希中是否存在密钥C
,如果是,请插入另一个密钥值对D
。
所以我的问题是,如何在不使用散列的变量名的情况下将对此散列的引用传递给sub?我希望需要对一些哈希进行此操作,我不想继续更改sub以引用它当前所在哈希的名称。
答案 0 :(得分:4)
你得到的是一些嵌套数组引用,而不是哈希。让我们假设你实际上意味着你有这样的东西:
my $h = { A => {...}, B => {...}, ..., EXPAND() };
在这种情况下,您无法在自己的定义中引用$h
,因为在完全评估表达式之前$h
不存在。
如果你满足于将其分为两行,那么你可以这样做:
my $h = { A=> {...}, B => {...} };
$h = { %$h, EXPAND( $h ) };
答案 1 :(得分:4)
一般的解决方案是编写一个函数,给定一个散列和扩展该散列的函数,返回添加了扩展函数的散列。我们可以在扩展函数中关闭哈希,以便不需要在其中提及哈希的名称。看起来像这样:
use strict;
use warnings;
use 5.010;
sub add_expander {
my ($expanding_hash, $expander_sub) = @_;
my $result = { %$expanding_hash };
$result->{EXPAND} = sub { $expander_sub->($result) };
return $result;
}
my $h = add_expander(
{
A => 5,
B => 6,
},
sub {
my ($hash) = @_;
my ($maxkey) = sort { $b cmp $a } grep { $_ ne 'EXPAND' } keys %$hash;
my $newkey = chr(ord($maxkey) + 1);
$hash->{$newkey} = 'BOO!';
}
);
use Data::Dumper;
say Dumper $h;
$h->{EXPAND}->();
say Dumper $h;
请注意,我们正在创建$h
,但add_expander
调用未提及$h
。相反,传入调用的子函数需要将其扩展的哈希作为其第一个参数。在sub上的散列上运行add_expander
会创建一个闭包,它将记住扩展器与哪个散列关联,并将其合并到散列中。
此解决方案假设在扩展哈希时应该发生的事情可能因主题哈希而异,因此add_expander
采用任意子。如果您不需要这种自由度,可以将扩展子项合并到add_expander
。
答案 2 :(得分:0)
正在构建的哈希(可能)在EXPAND()
运行后发生。我可能会使用这样的东西:
$h = EXPAND( { A=>... } )
如果原始版本需要保持原样,EXPAND(...)
返回修改后的hashref或克隆。