如何使用'子程序引用'作为散列键 [英] How to use a 'subroutine reference' as a hash key
问题描述
在以下示例代码中,
- 我可以创建对子例程($ subref)的引用,然后对其进行解引用以运行子例程(& $ subref)
- 我可以使用引用作为哈希'值',然后轻松取消引用
- 但我无法弄清楚如何将引用用作哈希'键'。当我将密钥从散列中取出时,Perl将该密钥解释为一个字符串值(而不是引用) - 我现在了解一个>(感谢这个网站!)。所以我试过Hash :: MultiKey,但是这似乎把它变成一个数组引用。我想把它当作一个子程序/代码引用,假设这是可能的?
其他想法?
use strict;
#use diagnostics;
使用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我的$ key(键%hash2){
printRef type is:。 REF($键) \\\
。
& {$ key}('bob','sue'); #不好
}
你好{
我$ $ =移动;
my $ name2 = shift;
打印hello $ name and $ name2\\\
;
}
这是返回的内容:
hello bob和sue
hello bob和sue
引用类型是:ARRAY
不是d:\temp\\处的代码引用\\ test.pl第21行。
一个正常的散列键只是一个字符串。
my $ coderef = sub {my($ name,$ name2) = @_;说你好$ name和$ name2; };
my%hash2 =($ coderef => 1,);
打印键%hash2; #'CODE(0x8d2280)'
绑定是修改该行为的常用方法,但哈希值: :MultiKey 不会帮助你,它有一个不同的目的:正如名字所说,你可能有多个键,但只有简单的字符串:
使用Hash :: MultiKey qw();
绑定我的%hash2,'Hash :: MultiKey';
$ hash2 {[$ coderef]} = 1;
foreach我的$ key(键%hash2){
说'引用的关键是:'。 REF($键);
表示'由数组引用的列表元素的引用 - 解引用关键字是:';
表示@ {$ key}的ref($ _); #没有输出,即简单的字符串
说'列表元素通过数组解引用键生成:';
表示$ _表示@ {$ key}; #'CODE(0x8d27f0)'
}
改为使用 Tie :: RefHash 。 (代码批评:优先使用 - >
>箭头来取消引用coderef。)
使用5.010;
使用strict;
使用警告FATAL => '所有';
使用Tie :: RefHash qw();
my $ coderef = sub {
my($ name,$ name2)= @_;
表示hello $ name和$ name2;
};
$ coderef->(qw(bob sue));
my%hash =(sayhi => $ coderef);
$ hash {sayhi} - >(qw(bob sue));
绑定我的%hash2,'Tie :: RefHash';
%hash2 =($ coderef => 1);
foreach我的$ key(键%hash2){
说'引用的关键是:'。 REF($键); #'CODE'
$ key->(qw(bob sue));
}
In Perl, I'm learning how to dereference 'subroutine references'. But I can't seem to use a subroutine reference as a hash 'key'.
In the following sample code,
- I can create a reference to a subroutine ($subref) and then dereference it to run the subroutine (&$subref)
- I can use the reference as a hash 'value' and then easily dereference that
- But I cannot figure out how to use the reference as a hash 'key'. When I pull the key out of the hash, Perl interprets the key as a string value (not a reference) - which I now understand (thanks to this site!). So I've tried Hash::MultiKey, but that seems to turn it into an array reference. I want to treat it as a subroutine/code reference, assuming this is somehow possible?
Any other ideas?
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";
}
This is what is returned:
hello bob and sue
hello bob and sue
Ref type is: ARRAY
Not a CODE reference at d:\temp\test.pl line 21.
That is correct, a normal hash key is only a string. Things that are not strings get coerced to their string representation.
my $coderef = sub { my ($name, $name2) = @_; say "hello $name and $name2"; };
my %hash2 = ( $coderef => 1, );
print keys %hash2; # 'CODE(0x8d2280)'
Tieing is the usual means to modify that behaviour, but Hash::MultiKey does not help you, it has a different purpose: as the name says, you may have multiple keys, but again only simple strings:
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)'
}
Instead, use Tie::RefHash. (Code critique: prefer this syntax with the ->
arrow for dereferencing a 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));
}
这篇关于如何使用'子程序引用'作为散列键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!