我正在尝试编写一些抽象代码,用于在相似对象列表中搜索第一个属性与特定值匹配的对象。为了做到这一点,我需要调用一堆访问器方法并一一检查它们的所有值。我想使用这样的抽象:
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;
}
是的,您可以通过这种方式调用方法。不涉及字符串(或任何其他)评估。
另外,根据数据类型,将 ==
替换为 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;
更新:诚然,第一个解决方案是不太困惑的解决方案,因此它是更好的选择。但作为回答问题的人,你也添加了一点糖,让自己变得有趣! ;-)
关于perl - 在 Perl 中,如何调用名称在字符串中的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2719246/