perl如何引用哈希本身

时间:2013-06-24 18:15:17

标签: perl reference

这可能看起来很奇怪,但是如何在哈希本身“内部”引用哈希?这就是我想要做的事情:

我在末尾有一个带有子的散列哈希,比如:

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

。我希望实现EXPAND以查看此哈希中是否存在密钥C,如果是,请插入另一个密钥值对D

所以我的问题是,如何在不使用散列的变量名的情况下将对此散列的引用传递给sub?我希望需要对一些哈希进行此操作,我不想继续更改sub以引用它当前所在哈希的名称。

3 个答案:

答案 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或克隆。