自动调用作为子例程引用的哈希值

iLi*_*irt 4 perl hash anonymous-function data-structures

我有一个散列,其中有一些值不是标量数据,而是返回标量数据的匿名子程序.我想让这对于在哈希中查找值的代码部分完全透明,这样它就不必知道某些哈希值可能是返回标量数据的匿名子例程而不仅仅是普通的标量数据.

为此,有没有办法在访问其密钥时执行匿名子例程,而不使用任何特殊语法?这是一个简化的例子,说明了目标和问题:

#!/usr/bin/perl

my %hash = (
    key1 => "value1",
    key2 => sub {
        return "value2"; # In the real code, this value can differ
    },
);

foreach my $key (sort keys %hash) {
    print $hash{$key} . "\n";
}
Run Code Online (Sandbox Code Playgroud)

我想要的输出是:

perl ./test.pl
value1
value2
Run Code Online (Sandbox Code Playgroud)

相反,这就是我得到的:

perl ./test.pl
value1
CODE(0x7fb30282cfe0)
Run Code Online (Sandbox Code Playgroud)

Ilm*_*nen 5

正如奥列格所指出的,可以使用各种或多或少的神秘技巧,如tie重载或魔术变量来做到这一点.然而,这将是不必要的复杂和毫无意义的混淆.像这样的技巧一样酷,在实际代码中使用它们至少99%的时间都是错误的.

在实践中,最简单和最干净的解决方案可能是编写一个带有标量的辅助子程序,如果它是代码引用,则执行它并返回结果:

sub evaluate {
    my $val = shift;
    return $val->() if ref($val) eq 'CODE';
    return $val;  # otherwise
}
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

foreach my $key (sort keys %hash) {
    print evaluate($hash{$key}) . "\n";
}
Run Code Online (Sandbox Code Playgroud)

  • *"而不是像绑架那样邪恶"*这种对抗争吵的反感是什么?*"通过对象执行类似的操作"*将导致更多代码.我唯一反对`tie`的是,代码比普通的Perl访问变量慢得多,因为它是用Perl而不是C编写的.除了巨大的数据结构之外什么都没关系 (2认同)