2017-01-16 2 views
0

Чтобы написать замыкание в 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?

+1

Такого рода вещи часто называют «фабрикой», и это то, что я пишу о совсем немного в [Intemediate Perl] (https://www.intermediateperl.com) и [Освоение Perl] (https://www.masteringperl.org). –

ответ

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 в своем закрытии.

+1

Не могли бы вы объяснить, что делает ваш код и как/почему он отличается от вопроса OPs для тех, кто может не понимать, что вы опубликовали? – stevieb

+1

@stevieb, OP использует псевдокод; mscha обеспечил реализацию. Но они также изменили все имена, из-за чего трудно увидеть параллель. Вот почему я опубликовал свой ответ, который на самом деле просто переписывает mscha. – ikegami

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(...); 

 Смежные вопросы

  • Нет связанных вопросов^_^