[英]In Perl, how can I call a method whose name I have in a string?
我正在尝试编写一些抽象代码,用于搜索属性与特定值匹配的第一个类似对象的列表。 为了做到这一点,我需要调用一堆访问器方法并逐个检查它们的所有值。 我想使用这样的抽象:
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
不存在。 或者是吗? 如果我有一个包含其名称的字符串,我该如何调用方法? 或者对整个问题有更好的解决方案吗?
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;
}
是的,您可以通过这种方式调用方法。 不涉及字符串(或任何其他)eval。 另外,根据数据类型替换==
with 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;
更新:不可否认,第一个解决方案是较少混淆的解决方案,所以最好。 但是,当有人回答问题时,你也加了一点糖,让它对你自己也很有趣! ;-)
功能方式很酷,但对于像我这样的假人eval规则:
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
大声笑
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.