perl如何引用hash本身



这似乎是一件奇怪的事情,但如何在"内部"哈希时引用哈希?以下是我要做的:

我有一个散列,末尾有一个子,比如:

my $h = { A => [...], B => [...], ..., EXPAND => sub { ... } };

我希望实现EXPAND,看看这个散列中是否存在密钥C,如果存在,则插入另一个键值对D

所以我的问题是,如何在不使用哈希的变量名的情况下将对该哈希的引用传递给子?我预计需要对一些散列执行此操作,并且我不想一直更改子以引用它当前所在的散列的名称。

这里有一些嵌套的数组引用,而不是散列。假设你的意思是你有这样的东西:

my $h = { A => {...}, B => {...}, ..., EXPAND() };

在这种情况下,不能从$h自己的定义中引用它,因为$h在表达式完全求值之前是不存在的。

如果你满足于把它做成两行,那么你可以这样做:

my $h = { A=> {...}, B => {...} };
$h = { %$h, EXPAND( $h ) };

一般的解决方案是编写一个函数,给定一个哈希和一个扩展该哈希的函数,返回该哈希并添加扩展函数。我们可以在扩展函数中关闭该哈希,这样就不需要在其中提及该哈希的名称。如下所示:

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。相反,传递到调用中的子期望它要扩展的哈希作为它的第一个参数。在子上的散列上运行add_expander会创建一个闭包,该闭包将记住扩展器与哪个散列相关联,并将其合并到散列中。

该解决方案假设扩展哈希时应该发生的事情可能因主题哈希而异,因此add_expander采用任意的sub。如果您不需要该自由度,可以将扩展sub合并到add_expander中。

正在构建的哈希(可能)发生在EXPAND()运行之后。我可能会使用这样的东西:

$h = EXPAND( { A=>... } )

其中EXPAND(...)返回修改后的hashref,如果原始hashref需要保持原样,则返回克隆。

最新更新