在Perl中,子例程如何获得指向自身的coderef?

时间:2010-03-31 15:26:04

标签: perl

出于学习目的,我正在四处寻找建筑的想法 Perl中的事件驱动程序,并注意到它可能会很好 注册为事件处理程序的子例程在失败时可以 只是为了以后安排另一个自己的电话。到目前为止,我有 拿出这样的东西:

my $cb;
my $try = 3;
$cb = sub {
    my $rc = do_stuff();
    if (!$rc && --$try) {
        schedule_event($cb, 10); # schedule $cb to be called in 10 seconds
    } else {
        do_other_stuff;
    }
};
schedule_event($cb, 0); # schedule initial call to $cb to be performed ASAP

是否存在sub中的代码可以访问coderef的方式 sub所以我可以不使用额外的变量?我想 安排这样的初始通话。

schedule_event( sub { ... }, 0);

我首先考虑使用caller(0)[3],但这只给了我一个 函数名称,(如果没有名称,则为__ANON__),而不是代码引用 有一个垫附在它上面。

5 个答案:

答案 0 :(得分:14)

我认为Sub::Current会解决您的问题。

答案 1 :(得分:14)

要在不使用额外变量的情况下获取对当前子例程的引用,可以使用函数式编程的工具Y-combinator,它基本上抽象出创建闭包的过程。这是一个perlish版本:

use Scalar::Util qw/weaken/;

sub Y (&) {
    my ($code, $self, $return) = shift;
    $return = $self = sub {$code->($self, @_)};
    weaken $self;  # prevent a circular reference that will leak memory
    $return;
}

schedule_event( Y { my $self = shift; ... }, 0);

答案 2 :(得分:14)

__SUB__已添加到5.16中,提供了这种可用性。

答案 3 :(得分:5)

如果您不再次更改$cb的值,则可以使用该值。如果没有,请定义一个标量来保存它,不要再次更改它。例如:

my $cb = do {
  my $sub;
  $sub = sub { contents using $sub here }
}

答案 4 :(得分:4)

使用定点组合器,您可以编写$ cb函数,就好像第一个参数是函数本身一样:

sub U {
  my $f = shift;
  sub { $f->($f, @_) }
}

my $cb = sub {
  my $cb = shift;
  ...
  schedule_event(U($cb), 10);
  ...
}

schedule_event(U($cb), 0);