in reply to Rebinding closures, possible?
If however you are not asking about the general case, but already know at closure creation time you will need this, you can return both the target closure and an updater closure:
Or you can combine the two in one closure and use some flag (internal or external) to indicate which action to take. E.g. when using an argument as trigger:#!/usr/bin/perl -wl sub gen_counter { my $a = shift; return sub { ++$a }, sub { $a = shift }; } my ($counter, $modifier) = gen_counter(3); print $counter->(); print $counter->(); $modifier->(8); print $counter->(); print $counter->(); # which prints: 4 5 9 10
which prints the same#!/usr/bin/perl -wl sub gen_counter { my $a = shift; return sub { @_ ? $a = shift : ++$a }; } my $counter = gen_counter(3); print $counter->(); print $counter->(); $counter->(8); print $counter->(); print $counter->();
update:I realize my answer tells how to modify a closure, not how to clone it as was asked. For cloning I'd just call the generator again. This is cheap since all generated closures share the code, only the sets of lexicals differ. Or even combine the two (calling the generator as a special closure operation), getting something like:
sub gen_closure { my ($a, $b, $c) = @_; return sub { if ($some_trigger) { # Calculate new $a, $b, $c based on e.g. the # new @_ and the old $a, $b and $c. return gen_closure($new_a, $new_b, $new_c); } # Do the normal closure action on $a, $b and $c here } }
|
|---|