Perl和闭包。是否有可能?

时间:2017-01-16 13:42:02

标签: perl closures

要在Perl中编写闭包,我们需要编写

sub test {
    my( $x, $y, $z ) =  @_;

    my $closure =  sub{ $x + $y + $z };
}

但有时,如果不是总是,子程序可能有很多行,我想把子程序的定义放在外面并使用类似的东西

my $z;

sub test {
    my( $x, $y ) =  @_;

    my $closure =  closure( 'subname', $x, $y, $z );
}

sub subname : closure ( $var1, $var2, $var3 ) {
    $var1 + $var2 + $var3
}

所以我可以从其他地方重用这个闭包

my $on2;

sub test_xxx {
    my( $other_name1, $on3 ) =  @_;

    my $closure =  closure( 'subname', $on3, $other_name1, $on2 );
}

这在Perl中是否可行?

2 个答案:

答案 0 :(得分:4)

closure定义如下:

sub closure {
    my ($sub_name, @args) = @_;
    my $sub = \&$subname;
    return sub { $sub->(@args) };
}

但是这种间接是没有用的。相反,只需替换

my $closure = closure( 'subname', $x, $y, $z );

my $closure = closure( 'subname', $on3, $other_name1, $on2 );

my $closure = sub { subname($x, $y, $z) };

my $closure = sub { subname($on3, $other_name1, $on2) };

如果你确实需要助手,那就不那么通用了。它通常会有一些特定于任务的准备代码,后跟return sub { };

sub make_foo_iter {
   my @args = @_;
   # ...
   return sub {
      # ...
   };
}

my $iter = make_foo_iter(...);

答案 1 :(得分:3)

尝试这样的事情:

use 5.012;
use warnings;

my $z;
sub test
{
    my ($x, $y) = @_;

    return sub { complicated_code($x, $y, $z) };
}

my $on2;
sub test_xxx
{
    my ($other_name1, $on3) =  @_;

    return sub { complicated_code($on3, $other_name1, $on2) };
}

sub complicated_code
{
    my ($a, $b, $c) = @_;

    return $a + $b + $c;
}

$z = 42;
my $closure = test(2,3);
say $closure->();       # 47
$z = 1;
say $closure->();       # 6

my $closure_xxx = test_xxx(4,5);
$on2 = 23;
say $closure_xxx->();   # 32

换句话说,在常规sub中添加许多行的复杂代码,只需在闭包中调用此sub