在 Perl 中,如何调用字符串中名称的方法?
Posted
技术标签:
【中文标题】在 Perl 中,如何调用字符串中名称的方法?【英文标题】:In Perl, how can I call a method whose name I have in a string? 【发布时间】:2011-02-12 17:42:42 【问题描述】:我正在尝试编写一些抽象代码,用于在相似对象列表中搜索其属性与特定值匹配的第一个对象。为了做到这一点,我需要调用一堆访问器方法并一个一个地检查它们的所有值。我想使用这样的抽象:
sub verify_attribute
my ($object, $attribute_method, $wanted_value) = @_;
if ( call_method($object, $attribute_method) ~~ $wanted_value )
return 1;
else
return;
然后我可以遍历一个散列,其键是访问器方法名称,其值是我正在寻找这些属性的值。例如,如果该哈希被称为%wanted
,我可能会使用这样的代码来查找我想要的对象:
my $found_object;
FINDOBJ: foreach my $obj (@list_of_objects)
foreach my $accessor (keys %wanted)
next FINDOBJ unless verify_attribute($obj, $accessor, $wanted$accessor);
# All attrs verified
$found_object = $obj;
last FINDOBJ;
当然,唯一的问题是call_method
不存在。或者是吗?如果我有一个包含方法名称的字符串,如何调用方法?或者对整个问题有更好的解决方案吗?
【问题讨论】:
【参考方案1】:my $found_object;
FINDOBJ: foreach my $obj (@list_of_objects)
foreach my $accessor (keys %wanted)
next FINDOBJ unless $obj->$accessor() == $wanted$accessor;
# All attrs verified
$found_object = $obj;
last;
是的,您可以通过这种方式调用方法。不涉及字符串(或任何其他)评估。
另外,根据数据的类型,将==
替换为eq
或=~
...
或者,对于一些额外的学分,以函数方式执行:(all() 确实应该是 List::Util 的一部分!)
use List::Util 'first';
sub all (&@)
my $code = shift;
$code->($_) || return 0 for @_;
return 1;
my $match = first
my $obj = $_;
all $obj->$_ == $attrs$_
keys %wanted
@list_of_objects;
更新:诚然,第一个解决方案是不太混淆的解决方案,所以它是可取的。但作为回答问题的人,你也添加了一点糖来让它变得有趣! ;-)
【讨论】:
是的,我只是在几秒钟前通过反复试验才弄清楚这一点。酷。 我只使用List::AllUtils
。或Util::Any qw( :all )
。但在我的示例代码中,我试图坚持核心。
我相信要使此功能起作用,您必须使用no strict;
(不一定是全局)禁用严格性检查——对吗?
@j_random_hacker:对于 $obj->$method?没有。根本不干扰“使用严格”。如果这就是你的想法,它不是一个象征性的参考。
@j_random_hacker => 我猜想为什么 $obj->$method
语法可以使用 strict 是因为它只是这个合法结构的语法糖:$obj->can($method)->($obj)
。而$func->()
或&$func()
没有任何“严格的法律”形式【参考方案2】:
功能方式很酷,但对于像我这样的傻瓜评估规则:
test.pl
#!/usr/bin/perl -l
use F;
my $f = F->new();
my $fun = 'lol'; # method of F
eval '$f->'.$fun.'() '; # call method of F, which name is in $fun var
F.pm
package F;
sub new
bless ;
sub lol
print "LoL";
1;
[root@ALT-24 root]# perl test.pl
大声笑
【讨论】:
以上是关于在 Perl 中,如何调用字符串中名称的方法?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Integration Java DSL:如何使用 channelMapping 方法路由到标题中名称的通道?