如何列出给定范围内的所有变量?

时间:2009-04-14 13:19:21

标签: perl

我知道我可以使用Padwalkerpeek_ourpeek_my列出给定范围内的所有包和词汇变量,但是如何获取所有的名称和值全局变量如$"$/

#!/usr/bin/perl

use strict;
use warnings;

use PadWalker qw/peek_our peek_my/;
use Data::Dumper;

our $foo = 1;
our $bar = 2;

{
    my $foo = 3;
    print Dumper in_scope_variables();
}

print Dumper in_scope_variables();

sub in_scope_variables {
    my %in_scope = %{peek_our(1)};
    my $lexical  = peek_my(1);
    #lexicals hide package variables
    while (my ($var, $ref) = each %$lexical) {
        $in_scope{$var} = $ref;
    }
    ##############################################
    #FIXME: need to add globals to %in_scope here#
    ##############################################
    return \%in_scope;
}

4 个答案:

答案 0 :(得分:32)

您可以访问符号表,请查看p。 “Perl编程”293 另请参阅“掌握Perl:http://www252.pair.com/comdog/mastering_perl/ 具体来说:http://www252.pair.com/comdog/mastering_perl/Chapters/08.symbol_tables.html

您要查找的那些变量将位于主命名空间

Google快速搜索给了我:

{
    no strict 'refs';

    foreach my $entry ( keys %main:: )
    {
        print "$entry\n";
    }
}

您也可以

*sym = $main::{"/"}

同样适用于其他值

如果你想找到你可以做的符号类型(来自掌握perl):

foreach my $entry ( keys %main:: )
{
    print "-" x 30, "Name: $entry\n";

    print "\tscalar is defined\n" if defined ${$entry};
    print "\tarray  is defined\n" if defined @{$entry};
    print "\thash   is defined\n" if defined %{$entry};
    print "\tsub    is defined\n" if defined &{$entry};
}

答案 1 :(得分:6)

就是这样。感谢MGoDave和kbosak在我面前提供答案,我看起来太傻了(我看着%main ::开始,但错过了他们没有他们的印记)。这是完整的代码:

#!/usr/bin/perl

use strict;
use warnings;

use PadWalker qw/peek_our peek_my/;
use Data::Dumper;

our $foo = 1;
our $bar = 2;

{
    my $foo = 3;
    print Dumper in_scope_variables();
}

print Dumper in_scope_variables();

sub in_scope_variables {
    my %in_scope = %{peek_our(1)};
    my $lexical  = peek_my(1);
    for my $name (keys %main::) {
        my $glob = $main::{$name};
        if (defined ${$glob}) {
            $in_scope{'$' . $name} = ${$glob};
        }

        if (defined @{$glob}) {
            $in_scope{'@' . $name} = [@{$glob}];
        }

        if (defined %{$glob}) {
            $in_scope{'%' . $name} = {%{$glob}};
        }
    }

    #lexicals hide package variables
    while (my ($var, $ref) = each %$lexical) {
        $in_scope{$var} = $ref;
    }
    return \%in_scope;
}

答案 2 :(得分:5)

您可以执行以下操作来检查主程序包的符号表:

{
    no scrict 'refs';

    for my $var (keys %{'main::'}) {
        print "$var\n";
    }
}

答案 3 :(得分:1)

谢谢,Chas,非常有用的代码。 作为您的代码的未来用户的注释,使用perl> 5.12:

我在我的pdl2 .perldlrc中使用它来找出词法变量(比如调试器中的'y'命令)并且我有这个警告:

  

load_rcfile:loading

     

/homes/pmg/.perldlrc定义的(%hash)在(eval 254)第36行弃用。

    (Maybe you should just omit the defined()?)

来自perldoc -f defined

  

在聚合上使用定义(哈希   和数组)已弃用。它曾经是   报告是否记忆   已经分配了总量。   这种行为将来可能会消失   Perl的版本。你应该改为   使用简单的大小测试:

>     if (@an_array) { print "has array elements\n" }
>     if (%a_hash) { print "has hash members\n" }

我不明白为什么它只是抱怨定义的哈希而不是数组?