perl - 如何使用 'subroutine reference' 作为哈希键

标签 perl hash reference subroutine dereference

在 Perl 中,我正在学习如何取消引用“子例程引用”。但我似乎无法使用子例程引用作为哈希“键”。

在以下示例代码中,

  1. 我可以创建对子例程 ($subref) 的引用,然后取消引用它以运行子例程 (&$subref)
  2. 我可以使用引用作为哈希“值”,然后轻松取消引用
  3. 但我不知道如何使用引用作为哈希“键”。当我从散列中取出 key 时,Perl 将该 key 解释为字符串值(而不是引用) - 我现在 understand (感谢这个网站!)。所以我尝试了 Hash::MultiKey,但这似乎将它变成了数组引用。我想将其视为子例程/代码引用,假设这在某种程度上是可能的?

还有其他想法吗?

use strict;
#use diagnostics;
use Hash::MultiKey;    

my $subref = \&hello;

#1: 
&$subref('bob','sue');               #okay

#2:
my %hash;
$hash{'sayhi'}=$subref;
&{$hash{'sayhi'}}('bob','sue');      #okay

#3: 
my %hash2;
tie %hash2, 'Hash::MultiKey';
$hash2{$subref}=1;
foreach my $key (keys %hash2) {
  print "Ref type is: ". ref($key)."\n";
  &{$key}('bob','sue');              # Not okay 
}

sub hello {
    my $name=shift;
    my $name2=shift;
    print "hello $name and $name2\n";
}

这是返回的内容:

hello bob and sue
hello bob and sue
Ref type is: ARRAY
Not a CODE reference at d:\temp\test.pl line 21.

最佳答案

这是正确的,普通的哈希键只是一个字符串。非字符串的内容被强制为其字符串表示形式。

my $coderef = sub { my ($name, $name2) = @_; say "hello $name and $name2"; };
my %hash2 = ( $coderef => 1, );
print keys %hash2;  # 'CODE(0x8d2280)'

Tie ing 是修改该行为的常用方法,但是 Hash::MultiKey对你没有帮助,它有不同的目的:正如名称所示,你可能有多个键,但同样只有简单的字符串:

use Hash::MultiKey qw();
tie my %hash2, 'Hash::MultiKey';
$hash2{ [$coderef] } = 1;
foreach my $key (keys %hash2) {
    say 'Ref of the key is: ' . ref($key);
    say 'Ref of the list elements produced by array-dereferencing the key are:';
    say ref($_) for @{ $key }; # no output, i.e. simple strings
    say 'List elements produced by array-dereferencing the key are:';
    say $_ for @{ $key }; # 'CODE(0x8d27f0)'
}

相反,请使用Tie::RefHash 。 (代码评论:更喜欢使用带有 -> 箭头的语法来取消对 coderef 的引用。)

use 5.010;
use strict;
use warnings FATAL => 'all';
use Tie::RefHash qw();

my $coderef = sub {
    my ($name, $name2) = @_;
    say "hello $name and $name2";
};

$coderef->(qw(bob sue));

my %hash = (sayhi => $coderef);
$hash{sayhi}->(qw(bob sue));

tie my %hash2, 'Tie::RefHash';
%hash2 = ($coderef => 1);
foreach my $key (keys %hash2) {
    say 'Ref of the key is: ' . ref($key);   # 'CODE'
    $key->(qw(bob sue));
}

关于perl - 如何使用 'subroutine reference' 作为哈希键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10795386/

相关文章:

regex - Vi 没有正确处理我的 perl 脚本中的大括号

python - 如何在 Python 中获取类属性的定义顺序?

linux - 无法在 Linux 上安装 PAR::Packer 1.014

windows - Perl Excel::Writer::XLSX-> new( 'myfile.xlsx' ) 在 Windows 8 环境中生成不适当的 I/O 错误

ruby - 访问 ruby​​ 数据结构的元素

c++ - 插入 unordered_map 时没有匹配函数

javascript - 如何引用任何给定行的表格单元格内的一组复选框

C++ 逗号运算符重载和引用 vector

c# - 基于常量的 Visual Studio 条件项目引用

perl - 如何将 Perl 输出发送到 STDOUT 和变量?