andreas1234567 has asked for the wisdom of the Perl Monks concerning the following question:

It says here ([Perl.sig] Perl Tip of the Week, March 2005) that:
Unfortunately, it's not possible to dump a subroutine reference using ''Data::Dumper'' or other tools. Perl doesn't (yet) have a way of turning a subroutine back into code. If we do pass a subroutine reference to Data::Dumper, it will instead print a place holder:
use Data::Dumper; print Dumper $sub_ref; # prints $VAR1 = sub { "DUMMY" };
This is easily confirmed on the command line:
$ perl use strict; use warnings; use Data::Dumper; my $coderef = sub { print "hello world\n"; }; print Dumper($coderef); __END__ $VAR1 = sub { "DUMMY" };
Have this evolved since March 2005? Are there ways to turn a reference to a subroutine back into code?

Update Fri Apr 18 09:50:54 CEST 2008: Thank you Monk with no name:

$ perl use strict; use warnings; use Data::Dumper; my $coderef = sub { print "hello world\n"; }; $Data::Dumper::Deparse=1; print Dumper($coderef); __END__ $VAR1 = sub { use warnings; use strict 'refs'; print "hello world\n"; };
--
When you earnestly believe you can compensate for a lack of skill by doubling your efforts, there's no end to what you can't do. [1]

Replies are listed 'Best First'.
Re: Turning a reference to a subroutine back into code
by citromatik (Curate) on Apr 18, 2008 at 07:52 UTC

    Data::Dump::Streamer can do that. Here is the different outputs you can get with Data::Dumper and Data::Dump::Streamer

    use strict; use warnings; use Data::Dumper; use Data::Dump::Streamer; sub makeGreeting { my $str = "Hello "; return sub { my ($name) = @_; print "$str $name\n"; } } my $greet = makeGreeting(); $greet->("Mike"); print "From Data::Dumper\n",Dumper $greet,"\n\n"; print "From Data::Dump::Streamer\n",Dump $greet;

    This code outputs:

    Hello Mike From Data::Dumper $VAR1 = sub { "DUMMY" }; From Data::Dump::Streamer my ($str); $str = 'Hello '; $CODE1 = sub { use warnings; use strict 'refs'; my($name) = @_; print "$str $name\n"; };

    Hope this helps

    citromatik

      I do this in Sub::Compose.

      My criteria for good software:
      1. Does it work?
      2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: Turning a reference to a subroutine back into code
by Anonymous Monk on Apr 18, 2008 at 07:31 UTC
    perldoc Data::Dumper
    $Data::Dumper::Deparse or $OBJ->Deparse([NEWVAL]) Can be set to a boolean value to control whether code references are t +urned into perl source code. If set to a true value, B::Deparse will +be used to get the source of the code reference. Using this option wi +ll force using the Perl implementation of the dumper, since the fast +XSUB implementation doesn't support it. Caution : use this option only if you know that your coderefs will be +properly reconstructed by B::Deparse.
Re: Turning a reference to a subroutine back into code
by FunkyMonk (Bishop) on Apr 18, 2008 at 08:24 UTC
    Another alternative is B::Deparse
    use B::Deparse; sub dumpsub { print "sub ",B::Deparse->new->coderef2text(shift),"\n" } dumpsub \&dumpsub;

    Output:

    sub { BEGIN {${^WARNING_BITS} = "\377\377\377\377\377\377\377\377\377\37 +7\377\177"} use strict 'refs'; print 'sub ', 'B::Deparse'->new->coderef2text(shift @_), "\n"; }


    Unless I state otherwise, my code all runs with strict and warnings

      Nice example

      Be aware that if you plan to do this with a closure, B::Deparse doesn't pack any variable that the subroutine has closed over. Here is the same example that I posted above using B::Deparse:

      use strict; use warnings; use B::Deparse; sub makeGreeting { my $str = "Hello "; return sub { my ($name) = @_; print "$str $name\n"; } } my $greet = makeGreeting(); my $deparse = B::Deparse->new(); print $deparse->coderef2text($greet);

      Outputs:

      { use warnings; use strict 'refs'; my($name) = @_; print "$str $name\n"; }

      Variable $str appears in the output but its declaration is not "packed" inside the code

      citromatik