Каков наилучший способ обнаружить все переменные, которые в настоящее время определены приложением Perl? - PullRequest
9 голосов
/ 09 апреля 2009

Я ищу лучший, самый простой способ сделать что-то вроде:

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

Ответы [ 5 ]

9 голосов
/ 09 апреля 2009

Пакетные переменные? Лексические переменные?

Переменные пакета можно найти через таблицу символов. Попробуйте 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();

Лексические переменные немного сложнее, вы не найдете их в таблице символов. Их можно найти через «блокнот», принадлежащий блоку кода, в котором они определены. Попробуйте 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 голосов
/ 09 апреля 2009

Таблица глобальных символов %main::, так что вы можете получить глобальные переменные оттуда. Тем не менее, каждая запись представляет собой глобус типа, который может содержать несколько значений, например, $ x, @x,% x и т. Д., Поэтому вам необходимо проверить каждый тип данных. Вы можете найти код, который делает это здесь . Комментарии на этой странице могут помочь вам найти другие решения для неглобальных переменных (например, лексических переменных, объявленных с помощью «my»).

6 голосов
/ 09 апреля 2009

Модуль PadWalker дает вам peek_my и peek_our, которые принимают аргумент LEVEL, который определяет, в какой области искать переменные:

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.

Вот пример:

#!/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 голос
/ 09 апреля 2009

Будет ли это для чего-то кроме целей отладки? Если нет, вы можете ознакомиться с отладчиком perl . Оказавшись внутри отладчика, вы можете проверить все переменные, введя «V».

1 голос
/ 09 апреля 2009

ответ Натана является частью истории - к сожалению, остальная часть истории состоит в том, что лексические переменные не перечислены ни в %main::, ни где-либо еще (по крайней мере, в любом месте, доступном из Perl - это возможно, можно написать какой-нибудь волосатый код XS, который копает эту информацию из внутренних элементов Perl C-level).

Лексические переменные - это то, что вы обычно используете для «обычных локальных» переменных. Они объявлены как:

my $x;
...