加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

如何在数组引用中使用索引作为Perl中的方法引用?

发布时间:2020-12-15 23:35:15 所属栏目:大数据 来源:网络整理
导读:与 this question about iterating over subroutine references类似,作为回答 this question about a OO dispatch table的结果,我想知道如何在引用中调用方法引用,而不是先删除它,或者甚至可能. 例如: package Class::Foo;use 5.012; #Yay autostrict!use w
与 this question about iterating over subroutine references类似,作为回答 this question about a OO dispatch table的结果,我想知道如何在引用中调用方法引用,而不是先删除它,或者甚至可能.

例如:

package Class::Foo;
use 5.012;   #Yay autostrict!
use warnings;

# a basic constructor for illustration purposes....
sub new { 
    my $class = shift;
    return bless {@_},$class;
}

# some subroutines for flavor...
sub sub1 { say 'in sub 1'; return shift->{a} }
sub sub2 { say 'in sub 2'; return shift->{b} }
sub sub3 { say 'in sub 3'; return shift->{c} }

# and a way to dynamically load the tests we're running...
sub sublist {
    my $self = shift; 
    return [
        $self->can('sub1'),$self->can('sub3'),$self->can('sub2'),];
}

package main;

sub get_index { ... } # details of how we get the index not important    

my $instance = Class::Foo->new(a => 1,b => 2,c => 3);
my $subs = $instance->sublist();
my $index = get_index();

# <-- HERE

那么,在HERE,我们可以做到:

my $ref = $subs->[$index];
$instance->$ref();

但是如果不首先删除引用,我们将如何做到这一点呢?

编辑:

更改了代码示例,以便人们不会对实现细节感到困惑(叹息,尽我所能).这与我给出的第一个链接之间的重要区别是该函数应该作为方法调用,而不是作为直接子例程调用.

编辑2:

请参阅discussion in the linked comment关于技术细节,以及为什么更长的方式(将subref存储到变量,然后调用它)可能更好.

解决方法

如上所述,你可以逃脱

$tests->[$index]();

因为你问题中的方法不是使用$self.

你可以明确地传递$instance,但这很笨重.更好的是模拟具有闭包的代理:

sub sublist {
    my $self = shift;
    my $sublist;
    for (qw/ sub1 sub3 sub2 /) {
      my $meth = $_;
      push @$sublist => sub { $self->$meth() };
    }
    return $sublist;
}

如果您想简洁,请使用

sub sublist {
    my $self = shift;
    return [ map { my $meth = $_; sub { $self->$meth() } }
             qw/ sub1 sub3 sub2 / ];
}

随机拨打一个仍然是

$tests->[$index]();

但现在方法得到了调用.

更新

通过can抓取subrefs似乎是不必要的复杂性.如果运行时确定要调用的方法名称列表,则可以大大简化代码:

sub sublist {
    my $self = shift; 
    return [ qw/ sub1 sub3 sub2 / ];
}

下面,我们将它们全部称为测试目的,但您也可以看到如何只调用一个:

foreach my $method (@$subs) {
  my $x = $instance->$method();
  say "$method returned $x";
}

输出:

in sub 1
sub1 returned 1
in sub 3
sub3 returned 3
in sub 2
sub2 returned 2

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读