2008-10-23 3 views
53

वहाँ एक रास्ता मैं एक पर्ल स्क्रिप्ट में एक मौजूदा पद से ठीक पहले उप कॉल की मनमाने ढंग से गहराई तक उप + मॉड्यूल की एक सूची (प्रिंटआउट के लिए) का उपयोग कर सकते है?मैं पर्ल में कॉल स्टैक सूची कैसे प्राप्त कर सकता हूं?

मैं कुछ पर्ल मॉड्यूल (.pm के) में परिवर्तन करने की जरूरत है। वर्कफ़्लो को एक सीजीआई-स्क्रिप्ट के माध्यम से वेब पेज से शुरू किया जाता है, जो मॉड्यूल में समाप्त होने वाले कई मॉड्यूल/ऑब्जेक्ट्स के माध्यम से इनपुट पास करता है जहां मुझे डेटा का उपयोग करने की आवश्यकता होती है। लाइन के साथ कहीं भी डेटा बदल गया और मुझे पता लगाने की जरूरत है कि कहां है।

उत्तर

56

आप Devel::StackTrace उपयोग कर सकते हैं।

use Devel::StackTrace; 
my $trace = Devel::StackTrace->new; 
print $trace->as_string; # like carp 

यह कार्प के निशान की तरह व्यवहार करता है, लेकिन आप फ्रेम पर अधिक नियंत्रण प्राप्त कर सकते हैं।

एक समस्या यह है कि संदर्भ stringified रहे हैं और अगर एक संदर्भित मूल्य परिवर्तन, आप इसे नहीं देख पाएंगे है। हालांकि, आप पूर्ण डेटा प्रिंट करने के लिए PadWalker के साथ कुछ सामान चाबुक कर सकते हैं (हालांकि यह बहुत बड़ा होगा)।

17

caller ऐसा कर सकते हैं, तो आप उस से भी अधिक जानकारी चाहते हो सकता है, हालांकि।

7

हालांकि यह आपके प्रश्न का उत्तर नहीं है कि यह आप अपनी समस्या को हल :-)

यहाँ एक तरह से कैसे यह पता लगाने की जो Mark Dominus

+0

मुझे लेख पढ़ने के लिए समय बनाना होगा - वास्तव में दिलचस्प लगता है। – slashmais

15
वहाँ

से अपने चर में परिवर्तन का वर्णन एक दिलचस्प लेख है मदद कर सकता है भी Carp::confess है और Carp::cluck

14

Carp::longmess जो भी आप चाहते हैं वह करेंगे, और यह मानक है।

use Carp qw<longmess>; 
use Data::Dumper; 
sub A { &B; } 
sub B { &C; } 
sub C { &D; } 
sub D { &E; } 

sub E { 
    # Uncomment below if you want to see the place in E 
    # local $Carp::CarpLevel = -1; 
    my $mess = longmess(); 
    print Dumper($mess); 
} 

A(); 
__END__ 
$VAR1 = ' at - line 14 
    main::D called at - line 12 
    main::C called at - line 10 
    main::B called at - line 8 
    main::A() called at - line 23 
'; 

मैं

my $stack_frame_re = qr{ 
    ^    # Beginning of line 
    \s*    # Any number of spaces 
    ([\w:]+)  # Package + sub 
    (?: [(] (.*?) [)])? # Anything between two parens 
    \s+    # At least one space 
    called [ ] at # "called" followed by a single space 
    \s+ (\S+) \s+ # Spaces surrounding at least one non-space character 
    line [ ] (\d+) # line designation 
}x; 

sub get_stack { 
    my @lines = split /\s*\n\s*/, longmess; 
    shift @lines; 
    my @frames 
     = map { 
       my ($sub_name, $arg_str, $file, $line) = /$stack_frame_re/; 
       my $ref = { sub_name => $sub_name 
         , args  => [ map { s/^'//; s/'$//; $_ } 
             split /\s*,\s*/, $arg_str 
             ] 
         , file  => $file 
         , line  => $line 
         }; 
       bless $ref, $_[0] if @_; 
       $ref 
      } 
      @lines 
     ; 
    return wantarray ? @frames : \@frames; 
} 
+1

लांगमेस अब कार्प की एक दस्तावेजी या स्वचालित रूप से निर्यात की गई सुविधा नहीं है। हालांकि: 'मेरा $ गड़बड़ = कार्प();' समान लेकिन समान व्यवहार प्रदान नहीं करेगा। –

1

एक इस उप के साथ आया है कि अधिक सुंदर (अब वैकल्पिक blessin 'कार्रवाई के साथ!): Devel::PrettyTrace

use Devel::PrettyTrace; 
bt; 
8

इस कोड को किसी भी अतिरिक्त बिना काम करता है मॉड्यूल। बस जहां आवश्यक हो उसे शामिल करें।

my $i = 1; 
print STDERR "Stack Trace:\n"; 
while ((my @call_details = (caller($i++)))){ 
    print STDERR $call_details[1].":".$call_details[2]." in function ".$call_details[3]."\n"; 
} 
+0

साफ तकनीक (हालांकि मुझे कहना होगा कि यह थोड़ी देर हो गया है क्योंकि मैंने पर्ल के साथ डब किया था :) – slashmais

+1

मुझे बहुत अच्छा कहना है! धन्यवाद :-) – frr

संबंधित मुद्दे

 संबंधित मुद्दे