2011-03-04 33 views
8

獲取變量名字符串,我想獲得一個變量的名稱的文本表示。舉例來說,這將是我要尋找的功能:在Perl

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

我想這是因爲我想寫一個調試功能是遞歸輸出傳遞變量的內容,我希望它的輸出變量的名稱所以如果我連續調用這個調試函數100次,那麼對於我在輸出中查看哪個變量將不會產生混淆。

我聽到的數據::自卸車和我不是一個球迷。如果有人能告訴我如何可能得到一串變量的名字,那就太好了。

謝謝!

+4

爲什麼不使用Perl內置的調試工具,而不是重新發明輪子? – Cfreak 2011-03-04 22:17:56

+1

我懷疑傑韋利::堆棧跟蹤將是一個更好的解決您的問題,那麼追捕變量名。 – Quentin 2011-03-04 22:18:33

+1

爲什麼你不是Data :: Dumper的粉絲?如果我們確切地知道你的要求是什麼以及Data :: Dumper不滿足它們的要求,那麼回答你的問題將會更容易。沒有進一步的信息,我所能做的就是推薦Data :: Dumper,因爲這是我使用的。 – 2011-03-04 22:19:55

回答

-2

「我」(詞彙)變量名被刪除,所以你不能得到他們的名字。正如elsearticle所述,程序包變量的名稱可以通過符號表項(*var)獲得。

8

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 
6

要做到這一點,你需要使用模塊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"; 
    } 
}