Xpoint
   [напомнить пароль]

Можно ли просканировать область имён (typeglob) пакета/модуля

Метки: [без меток]
2013-01-03 22:48:52 [обр] Principal AG(0/11)[досье]
Всем доброго в.с.
Возникла необходимость временами (в основном в целях отладки) выводить значения всех переменных определённых глобально для текущего пакета (модуля).
Вероятнее всего сделать это можно через таблицу символов typeglob. Но все найденные мной в документации обращения к ней делаются через конкретные имена, т.е заведомо зная то имя (список), который необходим.
А можно ли просканировать область typeglob пакета/модуля на предмет вывода всех имеющихся там записей определённого типа (SCALAR, HASH, CODE ...)?
Т.е. что-то типа:
foreach my *name (обращение к typeglob) {
   print *name{HASH};
}
Заранее спасибо.
спустя 51 минуту [обр] Евгений Седов aka KPbIC(38/176)[досье]
сообщение промодерировано
print keys %Package::;
спустя 23 часа [обр] Principal AG(0/11)[досье]

Большое спасибо за начальную подсказку, цикл вроде бы идёт.
Но вот вывести значения всёравно никак не получается:

  foreach (keys %My::Package::) {
    *v1 = *My::Package{$_};
    my $v2 = *v1{SCALAR};
    my $v3 = $$v2;
    my $v4 = $My::Package{$_};
    print qq{<p>$_ = *v1 , $v2 , $v3, $v4</p>};
  }

На выходе получаю:

schema = *v1 , SCALAR(0x1b03868) , ,
class_info = *v1 , SCALAR(0x1b03868) , ,
BEGIN = *v1 , SCALAR(0x1b03868) , ,
vvv = *v1 , SCALAR(0x1b03868) , ,
dsOpen = *v1 , SCALAR(0x1b03868) , ,
location = *v1 , SCALAR(0x1b03868) , ,
META = *v1 , SCALAR(0x1b03868) , ,
v1 = *v1 , SCALAR(0x1b03868) , ,
ISA = *v1 , SCALAR(0x1b03868) , ,
class_uri = *v1 , SCALAR(0x1b03868) , ,
VERSION = *v1 , SCALAR(0x1b03868) , ,

Т.е. имена видны, но вот значения как-то не достаются.
Наверное я сильно туплю, плз. не судите строго, с Perl уже очень давно не работал.

  1. И ещё что-то не получается задать имя пакета через переменную типа:
my $pkg = 'My::Package';

И дальше уже делать цикл и выводить значения через переменную.
Ещё раз заранее спасибо.

спустя 12 часов [обр] Евгений Седов aka KPbIC(38/176)[досье]
сообщение промодерировано
Значения у вас достаются, но значениями являются ссылки. Надо их разыменовать.
#! /usr/bin/perl

use strict; 
use warnings; 
 
package Pack; 
use vars qw/ $v1 /; 
 
$v1 = 25; 
 
while (my ($k,$v) = each %Pack::) { 
   no strict; 
   print "$k=$v"; 
   print "\tSCALAR=$$k\n" 
}
спустя 15 часов [обр] Principal AG(0/11)[досье]

Всё бы хорошо, но вот только работает такая конструкция только находясь внутри пакета, который сканирует.
Если запустить её за пределами пакета, то опять одни пустышки.
А смысл как раз в том, что бы из головного скрипта анализировать состояние других модулей, предварительно загруженных по use или require.
И всё никак не соображу, как докопаться до индексного хэша:

Стивен Холзнер:
Записи в таблице символов Perl - это хэши, которые содержат адреса всех именованных элементов текущего пакета. ... групповому имени соответствует хэш индексированный ключами SCALAR, HASH, CODE и т.д.

Вот в идеале хочется сделать цикл, который перебирает все имена имеющиеся в пакете (его мы вроде как сделали), а внутри него ещё запустить цикл, который проверяет каждое имя по типам, и если какой-то тип определён (не пустышка), то делает ему print.

спустя 9 часов [обр] Евгений Седов aka KPbIC(38/176)[досье]
сообщение промодерировано

Эта конструкция работает и из main:: для заюзанного пакета.

Вы уже докопались до хеша, вам осталось разыменовать ссылку: ${*$v{SCALAR}}

$ cat Pack.pm 
package Pack;

use vars qw/ $pv1 $pv2 @pv3 /;

$pv1 = 17;
$pv2 = 25;
@pv3 = (2, 3, 5, 7);

1;
$ cat script.pl 
#!/usr/bin/perl

use strict;
use warnings;

use lib '.';
use Pack;

while (my ($k,$v) = each %Pack::) {
    my $scalar = *$v{SCALAR};
    my $array  = *$v{ARRAY};
    print "$k; $v; $$scalar;\n" if defined $$scalar;
    print "$k; $v; @$array;\n" if defined $array;
}
$ ./script.pl
pv1; *Pack::pv1; 17;
pv3; *Pack::pv3; 2 3 5 7;
pv2; *Pack::pv2; 25;
спустя 22 часа [обр] Principal AG(0/11)[досье]
Огромное спасибо!
Всё прекрасно работает.
Попробую придать этому делу более-менее "товарный вид".
Если что путное получится, выложу здесь, может Вы меня ещё немного покритикуете.
Ещё раз спасибо.
Powered by POEM™ Engine Copyright © 2002-2005