This allows a user to inspect the contents of a code reference's pads. By default it returns all the pads in use so if this is used on a currently executing recursive function then it will return each instance. Since this is a viewer I didn't go to any attempt to provide a way to modify those pads. Five bucks and I'll think about doing that too.

This is for broquaint.

UPDATE: I altered the code to use Devel::Pointer::PP instead of Devel::Pointer. Its a bit more powerful than the XS version.

# Sample code use Data::Dumper; my $k = 42; my $j = sub { $k }; sub r { my $r = shift; $r--; if ( $r and $k and $j->() ) { r( $r ); } else { print Dumper( [ map $_->hash, PadViewer->new( \&r )->pads ] ); } } r( 10 );
package PadViewer; use strict; use 5.006; use warnings FATAL => 'all'; use B; sub new { my $class = shift; my $rv = shift; bless \ B::svref_2object( $rv ), $class; } sub pads { my $self = shift; return unless $$self and $$self->can('PADLIST') and $$self->PADLIST and $$self->PADLIST->can('ARRAY'); my ($names, @values) = $$self->PADLIST->ARRAY; map PadViewer::Pad->new( $names, $_), @values; } package PadViewer::Pad; use strict; use warnings FATAL => 'all'; use Devel::Pointer::PP; sub new { my $class = shift; my $names = shift; my $values = shift; bless { names => $names, values => $values }, $class; } sub names { my $self = shift; return unless $self->{'names'}->can('ARRAY') and $self->{'values'}->can('ARRAY'); my @n = $self->{'names'}->ARRAY; my @v = $self->{'values'}->ARRAY; map +((ref $n[$_] && $n[$_]->can('PV')) ? $n[$_]->PV : undef), grep _is_lexical($v[$_]), 0 .. $#v; } sub values { my $self = shift; return unless $self->{'values'}->can('ARRAY'); my @v = $self->{'values'}->ARRAY; map deref($$_), grep _is_lexical($_), @v; } sub hash { my $self = shift; my %h; @h{ $self->names } = $self->values; \ %h; } sub _is_lexical { my $padv = shift; $padv->can('FLAGS') and $padv->FLAGS & 0x400; } 1;

Replies are listed 'Best First'.
Re: PadViewer - a riff on PadWalker
by princepawn (Parson) on Sep 04, 2003 at 17:20 UTC
    Someone thought that PadWalker was useless, but I thought it was a neat way to calculate Fibonacci numbers!

    Carter's compass: I know I'm on the right track when by deleting something, I'm adding functionality... download and use The Emacs Code Browser

      So how did you do it?

        it's been awhile and in fact, when I wrote my fibo.pl using it, it wouldn't work due to a defect in PadWalker at that time but then he fixed that defect but I never got back to running my code... but if you know what Fibonacci numbers are and if you know that Padwalker allows you to look at previous elements of a stack, then you should be able to put 2 and 2 together quite easily, no?

        Carter's compass: I know I'm on the right track when by deleting something, I'm adding functionality... download and use The Emacs Code Browser