Update 4. Now implemented at Rebinding closures.
Guts muckery. You have a reference to a CV object which has a pointer to the external lexical scope via PADLIST. Past perl 5.8.x the B module includes a object_2svref which should allow you to turn PADLIST back into a normal array. Now you just substitute in your replacement array assuming you know what parts to edit and with what. Otherwise this is cough easy.
Update 2. Here's some code that does exactly what you asked for. The mutate() function replace the closure's bound value with a random value.
use B qw(class svref_2object); $\ = "\n"; my $rand = rand; $bar = sub { print $rand }; while (1) { mutate( $bar ); $bar->(); sleep 1; } sub mutate { (svref_2object($_[0])->PADLIST->ARRAY)[1]->object_2svref->[1] = ra +nd }
Update 1. If you can follow this then you're puissant enough to write the code that will replace the bindings to the pad variables. My thought is that it'd be neat to take a list of pairs of strings/regex and replacement regexes. That way you could examine the list of current variable names, if you had an exact match or a regex match against ->PADLIST->ARRAY->[0][$ix] then you replace the reference in ->PADLIST->ARRAY->[1][$ix].
use B qw(class svref_2object); use Data::Dumper; @a = map { my $k = rand; sub { print $k } } 0, 1; @a = map map( [ map +( class($_) ne 'SPECIAL' ? $_->object_2svref : $_ ), $_->ARRAY ], svref_2object($_)->PADLIST->ARRAY ), @a; print Dumper( @a );
Results in:
$VAR1 = [ bless( do{\(my $o = 1)}, 'B::SPECIAL' ), \'$k' ]; $VAR2 = [ [], \'0.681204496723698' ]; $VAR3 = [ bless( do{\(my $o = 1)}, 'B::SPECIAL' ), $VAR1->[1] ]; $VAR4 = [ [], \'0.716383141555951' ];
In reply to Re: Rebinding closures, possible?
by diotalevi
in thread Rebinding closures, possible?
by bsb
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |