2011-03-04 4 views
8

में स्ट्रिंग के रूप में परिवर्तनीय नाम प्राप्त करें मैं एक चर के नाम का एक टेक्स्ट प्रस्तुति प्राप्त करने का प्रयास कर रहा हूं। उदाहरण के लिए, इस समारोह मैं देख रहा हूँ होगा:पर्ल

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

मैं यह चाहता हूँ क्योंकि मैं एक डिबग समारोह है कि रिकर्सिवली एक पारित कर दिया चर की सामग्री को आउटपुट लिखने के लिए कोशिश कर रहा हूँ, मैं यह उत्पादन वेरिएबल का नाम करना चाहते हैं हाथ से पहले यदि मैं उत्तराधिकार में 100 बार इस डीबग फ़ंक्शन को कॉल करता हूं तो कोई भ्रम नहीं होगा क्योंकि आउटपुट में मैं किस चर को देख रहा हूं।

मैंने डेटा :: डम्पर के बारे में सुना है और मैं प्रशंसक नहीं हूं। अगर कोई मुझे बता सकता है कि यह कैसे संभव है कि एक चर के नाम की स्ट्रिंग प्राप्त हो, तो यह बहुत अच्छा होगा।

धन्यवाद!

+4

क्यों व्हील को पुनर्निर्मित करने के बजाय पर्ल के अंतर्निहित डिबगिंग टूल का उपयोग न करें? – Cfreak

+1

मुझे संदेह है कि डेवेल :: स्टैकट्रेस आपकी समस्या का बेहतर समाधान होगा, फिर परिवर्तनीय नामों को शिकार करना होगा। – Quentin

+1

आप डेटा :: डम्पर का प्रशंसक क्यों नहीं हैं? अगर हम जानते हैं कि आपकी आवश्यकताएं क्या हैं और क्यों डेटा :: डम्पर उन्हें संतुष्ट नहीं करता है, तो आपके प्रश्न का उत्तर देना आसान होगा। अधिक जानकारी के बिना, मैं बस डेटा :: डम्पर की सिफारिश कर सकता हूं क्योंकि मैं इसके लिए इसका उपयोग करता हूं। –

उत्तर

-2

"मेरा" (लेक्सिकल) चर के नाम मिटा दिए गए हैं, इसलिए आप उनके नाम नहीं प्राप्त कर सकते हैं। पैकेज वैरिएबल के नाम प्रतीक तालिका प्रविष्टि (*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"; 
    } 
} 
:

यहाँ ही कार्यक्षमता, एक बिट पुनर्संशोधित