use warnings; use strict; use B::Deparse; use Data::Dump qw/dd pp/; use Data::Dump::Filtered qw/add_dump_filter/; use Sub::Util qw/subname/; use PadWalker qw/closed_over/; my $deparse = B::Deparse->new(); $deparse->ambient_pragmas(strict=>'all', warnings=>'all'); add_dump_filter(sub { my ($ctx, $obj) = @_; if ( $ctx->is_code && subname($obj)=~/\b__ANON__\z/ ) { my $vars = closed_over($obj); return { dump => 'sub '.$deparse->coderef2text($obj), comment => join("\n", map { my $v = $vars->{$_}; "my $_ = ".( ref $v eq 'ARRAY' ? pp(@$v) : ref $v eq 'HASH' ? "(".join(", ", map { pp($_).' => ' .pp($v->{$_}) } sort keys %$v ).')' : pp($$v) ).';' } sort keys %$vars ), } } return undef; }); sub x { my $i = shift; my $y = { val=>123 }; return sub { $y->{val} += $i; my $z = 2; $i *= $z; return $y; } } my $foo = { bar => x(111), }; dd $foo; dd $foo->{bar}->(); dd $foo; __END__ { bar => # my $i = 111; # my $y = { val => 123 }; sub { $y->{'val'} += $i; my $z = 2; $i *= $z; return $y; }, } { val => 234 } { bar => # my $i = 222; # my $y = { val => 234 }; sub { $y->{'val'} += $i; my $z = 2; $i *= $z; return $y; }, }