Blame PadWalker.pm

Packit 074f87
package PadWalker;
Packit 074f87
Packit 074f87
use strict;
Packit 074f87
use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS);
Packit 074f87
Packit 074f87
require Exporter;
Packit 074f87
require DynaLoader;
Packit 074f87
Packit 074f87
require 5.008;
Packit 074f87
Packit 074f87
@ISA = qw(Exporter DynaLoader);
Packit 074f87
@EXPORT_OK = qw(peek_my peek_our closed_over peek_sub var_name set_closed_over);
Packit 074f87
%EXPORT_TAGS = (all => \@EXPORT_OK);
Packit 074f87
Packit 074f87
$VERSION = '2.3';
Packit 074f87
Packit 074f87
bootstrap PadWalker $VERSION;
Packit 074f87
Packit 074f87
sub peek_my;
Packit 074f87
sub peek_our;
Packit 074f87
sub closed_over;
Packit 074f87
sub peek_sub;
Packit 074f87
sub var_name;
Packit 074f87
Packit 074f87
1;
Packit 074f87
__END__
Packit 074f87
Packit 074f87
=head1 NAME
Packit 074f87
Packit 074f87
PadWalker - play with other peoples' lexical variables
Packit 074f87
Packit 074f87
=head1 SYNOPSIS
Packit 074f87
Packit 074f87
  use PadWalker qw(peek_my peek_our peek_sub closed_over);
Packit 074f87
  ...
Packit 074f87
Packit 074f87
=head1 DESCRIPTION
Packit 074f87
Packit 074f87
PadWalker is a module which allows you to inspect (and even change!)
Packit 074f87
lexical variables in any subroutine which called you. It will only
Packit 074f87
show those variables which are in scope at the point of the call.
Packit 074f87
Packit 074f87
PadWalker is particularly useful for debugging. It's even
Packit 074f87
used by Perl's built-in debugger. (It can also be used
Packit 074f87
for evil, of course.)
Packit 074f87
Packit 074f87
I wouldn't recommend using PadWalker directly in production
Packit 074f87
code, but it's your call. Some of the modules that use
Packit 074f87
PadWalker internally are certainly safe for and useful
Packit 074f87
in production.
Packit 074f87
Packit 074f87
=over 4
Packit 074f87
Packit 074f87
=item peek_my LEVEL
Packit 074f87
Packit 074f87
=item peek_our LEVEL
Packit 074f87
Packit 074f87
The LEVEL argument is interpreted just like the argument to C<caller>.
Packit 074f87
So C<peek_my(0)> returns a reference to a hash of all the C<my>
Packit 074f87
variables that are currently in scope;
Packit 074f87
C<peek_my(1)> returns a reference to a hash of all the C<my>
Packit 074f87
variables that are in scope at the point where the current
Packit 074f87
sub was called, and so on.
Packit 074f87
Packit 074f87
C<peek_our> works in the same way, except that it lists
Packit 074f87
the C<our> variables rather than the C<my> variables.
Packit 074f87
Packit 074f87
The hash associates each variable name with a reference
Packit 074f87
to its value. The variable names include the sigil, so
Packit 074f87
the variable $x is represented by the string '$x'.
Packit 074f87
Packit 074f87
For example:
Packit 074f87
Packit 074f87
  my $x = 12;
Packit 074f87
  my $h = peek_my (0);
Packit 074f87
  ${$h->{'$x'}}++;
Packit 074f87
Packit 074f87
  print $x;  # prints 13
Packit 074f87
Packit 074f87
Or a more complex example:
Packit 074f87
Packit 074f87
  sub increment_my_x {
Packit 074f87
    my $h = peek_my (1);
Packit 074f87
    ${$h->{'$x'}}++;
Packit 074f87
  }
Packit 074f87
Packit 074f87
  my $x=5;
Packit 074f87
  increment_my_x;
Packit 074f87
  print $x;  # prints 6
Packit 074f87
Packit 074f87
=item peek_sub SUB
Packit 074f87
Packit 074f87
The C<peek_sub> routine takes a coderef as its argument, and returns a hash
Packit 074f87
of the C<my> variables used in that sub. The values will usually be undefined
Packit 074f87
unless the sub is in use (i.e. in the call-chain) at the time. On the other
Packit 074f87
hand:
Packit 074f87
Packit 074f87
  my $x = "Hello!";
Packit 074f87
  my $r = peek_sub(sub {$x})->{'$x'};
Packit 074f87
  print "$$r\n";	# prints 'Hello!'
Packit 074f87
Packit 074f87
If the sub defines several C<my> variables with the same name, you'll get the
Packit 074f87
last one. I don't know of any use for C<peek_sub> that isn't broken as a result
Packit 074f87
of this, and it will probably be deprecated in a future version in favour of
Packit 074f87
some alternative interface.
Packit 074f87
Packit 074f87
=item closed_over SUB
Packit 074f87
Packit 074f87
C<closed_over> is similar to C<peek_sub>, except that it only lists
Packit 074f87
the C<my> variables which are used in the subroutine but defined outside:
Packit 074f87
in other words, the variables which it closes over. This I<does> have
Packit 074f87
reasonable uses: see L<Data::Dump::Streamer>, for example (a future version
Packit 074f87
of which may in fact use C<closed_over>).
Packit 074f87
Packit 074f87
=item set_closed_over SUB, HASH_REF
Packit 074f87
Packit 074f87
C<set_closed_over> reassigns the pad variables that are closed over by the subroutine.
Packit 074f87
Packit 074f87
The second argument is a hash of references, much like the one returned from C<closed_over>.
Packit 074f87
Packit 074f87
=item var_name LEVEL, VAR_REF
Packit 074f87
Packit 074f87
=item var_name SUB,   VAR_REF
Packit 074f87
Packit 074f87
C<var_name(sub, var_ref)> returns the name of the variable referred to
Packit 074f87
by C<var_ref>, provided it is a C<my> variable used in the sub. The C<sub>
Packit 074f87
parameter can be either a CODE reference or a number. If it's a number,
Packit 074f87
it's treated the same way as the argument to C<peek_my>.
Packit 074f87
Packit 074f87
For example,
Packit 074f87
Packit 074f87
  my $foo;
Packit 074f87
  print var_name(0, \$foo);    # prints '$foo'
Packit 074f87
  
Packit 074f87
  sub my_name {
Packit 074f87
    return var_name(1, shift);
Packit 074f87
  }
Packit 074f87
  print my_name(\$foo);        # ditto
Packit 074f87
Packit 074f87
=back
Packit 074f87
Packit 074f87
=head1 AUTHOR
Packit 074f87
Packit 074f87
Robin Houston <robin@cpan.org>
Packit 074f87
Packit 074f87
With contributions from Richard Soberberg, Jesse Luehrs and
Packit 074f87
Yuval Kogman, bug-spotting from Peter Scott, Dave Mitchell and
Packit 074f87
Goro Fuji, and suggestions from demerphq.
Packit 074f87
Packit 074f87
=head1 SEE ALSO
Packit 074f87
Packit 074f87
Devel::LexAlias, Devel::Caller, Sub::Parameters
Packit 074f87
Packit 074f87
=head1 COPYRIGHT
Packit 074f87
Packit 074f87
Copyright (c) 2000-2009, Robin Houston. All Rights Reserved.
Packit 074f87
This module is free software. It may be used, redistributed
Packit 074f87
and/or modified under the same terms as Perl itself.
Packit 074f87
Packit 074f87
=cut