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.

Reply via email to