在 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 方法路由到标题中名称的通道?

如何获取包含多选列表中所有选定项目的字符串?

如何在 Perl 中将字符串中每个单词的首字母大写?

REGEXP oracle几个not语句

如何使用 Perl 计算文件中的字符、单词和行数?

如何使用 Perl 在文件中查找扩展的 ASCII 字符?