Randal L. Schwartz wrote in perl.fwp :
>
> sub black_adder {
> my $constant = shift;
> sub { $constant + shift; }
> }
>
> my $to_deparse = black_adder(42);
> use B::Deparse;
> print "\n", B::Deparse->new->coderef2text($to_deparse), "\n";
>
>==>
>
> {
> $constant + shift(@_);
> }
>
> Ayup. That's the one. *What* constant? :) And that was the
> first odd one I tried. I could probably construct weirder ones
> once that one is fixed.
What do you expect B::Deparse::coderef2text to do here ? Output
something equivalent to { 42 + shift } ? or produce an error ("can't
deparse a closure without complete lexical context") ?
I think that the ideal thing to do is to allow deparsing closures when
the invocation to coderef2text is done at a point where the outside
lexical contexts have been closed -- and fail otherwise. For example, it
should refuse to deparse in the following situation :
sub foo {
my $constant = shift;
my $closure = sub { $constant + shift };
print B::Deparse->new->coderef2text($closure); # should be forbidden !
++$constant;
$closure;
}
print B::Deparse->new->coderef2text(foo(42)); # but OK here.
This shouldn't be very hard to fix (once the appropriate tuits about
CvOUTSIDE and other padlists are harvested.) A neat little fun-with-perl
project for anyone.