What’s the best way to discover all variables a Perl application has currently defined?

前端 未结 5 1887
太阳男子
太阳男子 2020-12-30 11:01

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

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

相关标签:
5条回答
  • 2020-12-30 11:19

    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;
    
    0 讨论(0)
  • 2020-12-30 11:27

    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);
    
    0 讨论(0)
  • 2020-12-30 11:28

    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";
        }
    }
    
    0 讨论(0)
  • 2020-12-30 11:28

    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'.

    0 讨论(0)
  • 2020-12-30 11:36

    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").

    0 讨论(0)
提交回复
热议问题