perl - sirven - ¿Cómo puedo enumerar todas las variables que están en un ámbito determinado?
porque los hashtags no me sirven en instagram (4)
Sé que puedo enumerar todas las variables de paquetes y lexiales en un ámbito determinado utilizando las Padwalker
peek_our
y peek_my
, pero ¿cómo puedo obtener los nombres y valores de todas las variables globales como $"
y $/
?
#!/usr/bin/perl
use strict;
use warnings;
use PadWalker qw/peek_our peek_my/;
use Data::Dumper;
our $foo = 1;
our $bar = 2;
{
my $foo = 3;
print Dumper in_scope_variables();
}
print Dumper in_scope_variables();
sub in_scope_variables {
my %in_scope = %{peek_our(1)};
my $lexical = peek_my(1);
#lexicals hide package variables
while (my ($var, $ref) = each %$lexical) {
$in_scope{$var} = $ref;
}
##############################################
#FIXME: need to add globals to %in_scope here#
##############################################
return /%in_scope;
}
Gracias, Chas, código muy útil. Como nota para futuros usuarios de su código con perl> 5.12:
Lo estaba usando en mi pdl2 .perldlrc para encontrar variables léxicas (como el comando ''y'' en el depurador) y tuve esta advertencia:
load_rcfile: cargando
/homes/pmg/.perldlrc definido (% hash) está en desuso en (eval 254) línea 36.
(Maybe you should just omit the defined()?)
De perldoc -f definido
El uso de definido en los agregados (hash y arrays) está en desuso. Solía informar si alguna vez se había asignado memoria para ese agregado. Este comportamiento puede desaparecer en versiones futuras de Perl. En su lugar, debe usar una prueba simple para el tamaño:
> if (@an_array) { print "has array elements/n" }
> if (%a_hash) { print "has hash members/n" }
Lo que no entiendo es ¿por qué solo se quejó con el hash definido y no también con el array?
Puede hacer algo como lo siguiente para verificar la tabla de símbolos del paquete principal:
{
no scrict ''refs'';
for my $var (keys %{''main::''}) {
print "$var/n";
}
}
Puedes acceder a la tabla de símbolos, echa un vistazo a p. 293 de "Programming Perl" Consulte también "Mastering Perl: http://www252.pair.com/comdog/mastering_perl/ Específicamente: http://www252.pair.com/comdog/mastering_perl/Chapters/08.symbol_tables.html
Esas variables que está buscando estarán debajo del espacio de nombres principal
Una rápida búsqueda en Google me dio:
{
no strict ''refs'';
foreach my $entry ( keys %main:: )
{
print "$entry/n";
}
}
También puedes hacer
*sym = $main::{"/"}
y lo mismo para otros valores
Si desea encontrar el tipo de símbolo que puede hacer (desde el dominio de perl):
foreach my $entry ( keys %main:: )
{
print "-" x 30, "Name: $entry/n";
print "/tscalar is defined/n" if defined ${$entry};
print "/tarray is defined/n" if defined @{$entry};
print "/thash is defined/n" if defined %{$entry};
print "/tsub is defined/n" if defined &{$entry};
}
Y eso lo hace. Gracias a MGoDave y a kbosak por darme la respuesta frente a mi cara que era demasiado estúpida para ver (busqué en% main :: para empezar, pero me perdí de que no tuvieran sus sellos). Aquí está el código completo:
#!/usr/bin/perl
use strict;
use warnings;
use PadWalker qw/peek_our peek_my/;
use Data::Dumper;
our $foo = 1;
our $bar = 2;
{
my $foo = 3;
print Dumper in_scope_variables();
}
print Dumper in_scope_variables();
sub in_scope_variables {
my %in_scope = %{peek_our(1)};
my $lexical = peek_my(1);
for my $name (keys %main::) {
my $glob = $main::{$name};
if (defined ${$glob}) {
$in_scope{''$'' . $name} = ${$glob};
}
if (defined @{$glob}) {
$in_scope{''@'' . $name} = [@{$glob}];
}
if (defined %{$glob}) {
$in_scope{''%'' . $name} = {%{$glob}};
}
}
#lexicals hide package variables
while (my ($var, $ref) = each %$lexical) {
$in_scope{$var} = $ref;
}
return /%in_scope;
}