What’s the best way to discover all variables a Pe

2019-02-04 21:53发布

问题:

I am looking for best, easiest way to do something like:

$var1="value";
bunch of code.....
**print allVariablesAndTheirValuesCurrentlyDefined;**

回答1:

Package variables? Lexical variables?

Package variables can be looked up via the symbol table. Try Devel::Symdump:

#!/path/to/perl

use Devel::Symdump;

package example;

$var = "value";
@var = ("value1", "value2");
%var = ("key1" => "value1", "key2" => "value2");

my $obj = Devel::Symdump->new('example');

print $obj->as_string();

Lexical variables are a little tricker, you won't find them in the symbol table. They can be looked up via the 'scratchpad' that belongs to the block of code they're defined in. Try PadWalker:

#!/path/to/perl

use strict;
use warnings;

use Data::Dumper;
use PadWalker qw(peek_my);

my $var = "value";
my @var = ("value1", "value2");
my %var = ("key1" =>  "value1", "key2" => "value2");

my $hash_ref = peek_my(0);

print Dumper($hash_ref);


回答2:

The global symbol table is %main::, so you can get global variables from there. However, each entry is a typeglob which can hold multiple values, e.g., $x, @x, %x, etc, so you need to check for each data type. You can find code that does this here. The comments on that page might help you find other solutions for non-global variables (like lexical variables declared with "my").



回答3:

The PadWalker module gives you peek_my and peek_our which take a LEVEL argument that determines which scope to look for variables in:

The LEVEL argument is interpreted just like the argument to caller.
So peek_my(0) returns a reference to a hash of all the my variables
that are currently in scope; peek_my(1) returns a reference to a hash
of all the my variables that are in scope at the point where the 
current sub was called, and so on.

Here is an example:

#!/usr/bin/perl

use strict;
use warnings;

use PadWalker qw/peek_my/;

my $baz = "hi";

foo();

sub foo {
    my $foo = 5;
    my $bar = 10;

    print "I have access to these variables\n";
    my $pad = peek_my(0);
    for my $var (keys %$pad) {
        print "\t$var\n";
    }

    print "and the caller has these variables\n";
    $pad = peek_my(1);
    for my $var (keys %$pad) {
        print "\t$var\n";
    }
}


回答4:

Nathan's answer is part of the story -- unfortunately, the rest of the story is that lexical variables aren't listed in %main:: or anywhere else (at least anywhere accessible from Perl -- it's probably possible to write some hairy XS code that digs this information out of Perl's C-level internals).

Lexical variables are what you would normally use for "ordinary local" variables. They are declared like:

my $x;


回答5:

Would this be for anything other than debugging purposes? If not, you may want to familiarize yourself with perl's debugger. Once inside the debugger you can inspect all variables by issuing 'V'.