在Perl中,如何在字符串中调用名称为的方法?

时间:2010-04-27 06:47:00

标签: perl string oop methods symbols

我正在尝试编写一些抽象代码,用于搜索属性与特定值匹配的第一个类似对象的列表。为了做到这一点,我需要调用一堆访问器方法并逐个检查它们的所有值。我想使用这样的抽象:

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不存在。或者是吗?如果我有一个包含其名称的字符串,我该如何调用方法?或者对整个问题有更好的解决方案吗?

2 个答案:

答案 0 :(得分:5)

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。 另外,将==替换为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;

更新:不可否认,第一个解决方案是不太混淆的解决方案,所以最好。但是,当有人回答问题时,你也加了一点糖,让它对你自己也很有趣! ; - )

答案 1 :(得分:0)

功能方式很酷,但对于像我这样的假人评估规则:

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

大声笑