2009-04-09 10 views
9

szukam najlepszy, najprostszy sposób zrobić coś takiego:Jaki jest najlepszy sposób na odkrycie wszystkich zmiennych, które obecnie określa aplikacja Perl?

$var1="value"; 
bunch of code..... 
**print allVariablesAndTheirValuesCurrentlyDefined;** 
+0

Myślę, że Data :: Dumper może być w stanie to zrobić, ale nie wiem jak. –

+0

Brian mówi prawdę. Najlepszą odpowiedzią jest "nie", a po niej "dlaczego chciałeś to zrobić?" – Schwern

+0

Brian/Schwern, wygląda na to, że jest tam nowe pytanie: "prawa do meta i krzywda". Czy możesz wskazać mi jakieś pytania lub linki na temat kiedy i dlaczego "refleksja" jest złym pomysłem. Zasadniczo chciałbym zawinąć niektóre istniejące perl z nowym perl bez zmian do istniejącej aplikacji –

Odpowiedz

9

Zmienne pakietowe? Zmienne leksykalne?

Zmienne pakietowe można przejrzeć za pomocą tabeli symboli. Spróbuj Devel::Symdump:

#!/path/to/perl 

use Devel::Symdump; 

package example; 

$var = "value"; 
@var = ("value1", "value2"); 
%var = ("key1" => "value1", "key2" => "value2"); 

my $obj = Devel::Symdump->new('example'); 

print $obj->as_string(); 

zmienne leksykalne są trochę tricker, nie znajdziesz ich w tablicy symboli. Mogą być spojrzał przez „scratchpad” należącym do bloku kodu są one zdefiniowane w Wypróbuj PadWalker.

#!/path/to/perl 

use strict; 
use warnings; 

use Data::Dumper; 
use PadWalker qw(peek_my); 

my $var = "value"; 
my @var = ("value1", "value2"); 
my %var = ("key1" => "value1", "key2" => "value2"); 

my $hash_ref = peek_my(0); 

print Dumper($hash_ref); 
7

globalna tablica symboli jest %main::, dzięki czemu można uzyskać zmienne globalne stamtąd. Jednak każdy wpis to typeglob, który może zawierać wiele wartości, np. $ X, @x,% x, itp., Więc musisz sprawdzić dla każdego typu danych. Możesz znaleźć kod, który to robi here. Komentarze na tej stronie mogą pomóc w znalezieniu innych rozwiązań dla zmiennych innych niż globalne (takich jak zmienne leksykalne zadeklarowane jako "moje").

+0

I nie zapomnij o wszystkich innych pakietach, które mają zmienne również w zakresie! –

+0

+1, ale proszę również nadmienić, że zmienne leksykalne (deklarowane jako "moje $ x;") nie są wymienione w% main :: ani nigdzie indziej. :( –

+0

+1, jednak nie można zagwarantować, że podany link będzie zawsze działał, nawet jeśli perlmonks będzie trwał wiecznie, witryna może zostać zreorganizowana.Warto podać trochę informacji o używaniu '% main ::' w odpowiedzi. –

1

Nathan's answer jest częścią historii - niestety, reszta historii jest to, że zmienne leksykalne nie są wymienione w %main:: lub gdziekolwiek indziej (przynajmniej nigdzie dostępny od Perl - to chyba można napisać kod owłosioną XS który wykopuje te informacje z wewnętrznych elementów Perla na poziomie C).

Zmienne leksykalne są zwykle używane w przypadku zmiennych "zwykłych lokalnych". Są one zadeklarowane jak:

my $x; 
+0

Na szczęście ktoś napisał już owłosiony kod XS. Zobacz PadWalker na CPAN. –

+0

@Chas: Interesujące. Chociaż czułbym się brudny używając PadWalker;) –

+0

W kodzie produkcyjnym? nigdy. W dev kodu, nie ma problemu. Pomyśl o tym jako programowalnym debuggerze, w rzeczywistości, uważam, że jest on używany przez Devel :: ebug do dostarczania zmiennych do zegarka. –

6

Moduł PadWalker daje peek_my i peek_our która przyjmowała argumentu poziomu, który określa, który zakres szukać zmiennych:

The LEVEL argument is interpreted just like the argument to caller. 
So peek_my(0) returns a reference to a hash of all the my variables 
that are currently in scope; peek_my(1) returns a reference to a hash 
of all the my variables that are in scope at the point where the 
current sub was called, and so on. 

Oto przykład:

#!/usr/bin/perl 

use strict; 
use warnings; 

use PadWalker qw/peek_my/; 

my $baz = "hi"; 

foo(); 

sub foo { 
    my $foo = 5; 
    my $bar = 10; 

    print "I have access to these variables\n"; 
    my $pad = peek_my(0); 
    for my $var (keys %$pad) { 
     print "\t$var\n"; 
    } 

    print "and the caller has these variables\n"; 
    $pad = peek_my(1); 
    for my $var (keys %$pad) { 
     print "\t$var\n"; 
    } 
} 
1

Mogłoby to być coś innego niż dla celów debugowania? Jeśli nie, możesz zapoznać się z perl's debugger. Po wejściu do debuggera możesz sprawdzić wszystkie zmienne, wydając "V".

+0

Nie, nie tak bardzo do debugowania, byłby to element "dynamicznego" ładowania środowiska wykonawczego, a następnie obliczenia, co zostało załadowane –

Powiązane problemy