在Perl中将变量名称作为字符串获取

时间:2011-03-04 22:11:00

标签: perl variables

我正在尝试获取变量名称的文本表示。例如,这将是我正在寻找的功能:

$abc = '123';
$var_name = &get_var_name($abc); #returns '$abc'

我想要这个,因为我正在尝试编写一个递归输出传递变量内容的调试函数,我希望它能在手工输出变量的名称,所以如果我连续100次调用这个调试函数就没有了关于我在输出中看到哪个变量的混淆。

我听说过Data :: Dumper并且不是粉丝。如果有人可以告诉我如何获得一个变量名称的字符串,那就太好了。

谢谢!

3 个答案:

答案 0 :(得分:9)

Data::Dumper::Simple

use warnings;
use strict;
use Data::Dumper::Simple;

my $abc = '123';
my ($var_name) = split /=/, Dumper($abc);
print $var_name, "\n";

__END__

$abc

答案 1 :(得分:7)

为此,您需要使用模块PadWalker,它允许您检查存储变量的词法填充。

use PadWalker qw/peek_my peek_our/;

sub debug {
    my $my     = peek_my 1;
    my $our    = peek_our 1;
    my $caller = caller() . '::';
    my $stash  = do {
        no strict 'refs';
        \%$caller
    };
    my %lookup;
    for my $pad ($my, $our) {
        $lookup{$$pad{$_}} ||= $_ for keys %$pad;
    }
    for my $name (keys %$stash) {
        if (ref \$$stash{$name} eq 'GLOB') {
            for (['$' => 'SCALAR'],
                 ['@' => 'ARRAY'],
                 ['%' => 'HASH'],
                 ['&' => 'CODE']) {
                if (my $ref = *{$$stash{$name}}{$$_[1]}) {
                    $lookup{$ref} ||= $$_[0] . $caller . $name
                }
            }
        }
    }
    for (@_) {
       my $name = $lookup{\$_} || 'name not found';
       print "$name: $_\n";
    }
}

然后使用它:

my $x = 5;
our $y = 10;
$main::z = 15;

debug $x, $y, $main::z;

打印:

$x: 5
$y: 10
$main::z: 15

编辑:

这是相同的功能,重构了一点:

use PadWalker qw/peek_my peek_our/;

sub get_name_my {
    my $pad = peek_my($_[0] + 1);
    for (keys %$pad) {
        return $_ if $$pad{$_} == \$_[1]
    }
}
sub get_name_our {
    my $pad = peek_our($_[0] + 1);
    for (keys %$pad) {
        return $_ if $$pad{$_} == \$_[1]
    }
}
sub get_name_stash {
    my $caller = caller($_[0]) . '::';
    my $stash = do {
        no strict 'refs';
        \%$caller
    };
    my %lookup;
    for my $name (keys %$stash) {
        if (ref \$$stash{$name} eq 'GLOB') {
            for (['$' => 'SCALAR'],
                 ['@' => 'ARRAY'],
                 ['%' => 'HASH'],
                 ['&' => 'CODE']) {
                if (my $ref = *{$$stash{$name}}{$$_[1]}) {
                    $lookup{$ref} ||= $$_[0] . $caller . $name
                }
            }
        }
    }
    $lookup{\$_[1]}
}
sub get_name {
    unshift @_, @_ == 2 ? 1 + shift : 1;
    &get_name_my  or
    &get_name_our or
    &get_name_stash
}

sub debug {
    for (@_) {
       my $name = get_name(1, $_) || 'name not found';
       print "$name: $_\n";
    }
}

答案 2 :(得分:-3)

“我的”(词汇)变量的名称被删除,因此您无法获得他们的名字。包变量的名称可通过符号表条目(*var)获得,如其他文章所述。