В полностью общем случае, вы не можете делать то, что вы хотите получить следующую выдержку из perlref:
*foo{THING}
возвращает undef
, если это значение THING еще не используется, за исключением случаев, когда скаляры. *foo{SCALAR}
возвращает ссылку на анонимный скаляр, если $foo
еще не был использован. Это может измениться в будущей версии.
Но если вы готовы принять ограничение, что любое скалярное должен иметь определенное значение, которое будет обнаружено, то вы можете использовать код, например
#! /usr/bin/perl
use strict;
use warnings;
open my $fh, "<", \$_; # get DynaLoader out of the way
my %before = %main::;
require "my.config";
my %after = %main::;
foreach my $name (sort keys %after) {
unless (exists $before{$name}) {
no strict 'refs';
my $glob = $after{$name};
print "\$$name\n" if defined ${ *{$glob}{SCALAR} };
print "\@$name\n" if defined *{$glob}{ARRAY};
print "%$name\n" if defined *{$glob}{HASH};
print "&$name\n" if defined *{$glob}{CODE};
print "$name (format)\n" if defined *{$glob}{FORMAT};
print "$name (filehandle)\n" if defined *{$glob}{IO};
}
}
получит Вас там.
С my.config
из
$JACKPOT = 3_756_788;
$YOU_CANT_SEE_ME = undef;
@OPTIONS = qw/ apple cherries bar orange lemon /;
%CREDITS = (1 => 1, 5 => 6, 10 => 15);
sub is_jackpot {
local $" = ""; # " fix Stack Overflow highlighting
"@_[0,1,2]" eq "barbarbar";
}
open FH, "<", \$JACKPOT;
format WinMessage =
You win!
.
Выходом является
%CREDITS
FH (filehandle)
$JACKPOT
@OPTIONS
WinMessage (format)
&is_jackpot
Печать имен занимает мало работы, но мы можем использовать модуль Data::Dumper
принять часть бремени. Вводная похож:
#! /usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
sub _dump {
my($ref) = @_;
local $Data::Dumper::Indent = 0;
local $Data::Dumper::Terse = 1;
scalar Dumper $ref;
}
open my $fh, "<", \$_; # get DynaLoader out of the way
my %before = %main::;
require "my.config";
my %after = %main::;
Нам нужно сбросить различные слоты немного по-разному и в каждом случае удалить атрибуты ссылок:
my %dump = (
SCALAR => sub {
my($ref,$name) = @_;
return unless defined $$ref;
"\$$name = " . substr _dump($ref), 1;
},
ARRAY => sub {
my($ref,$name) = @_;
return unless defined $ref;
for ("\@$name = " . _dump $ref) {
s/= \[/= (/;
s/\]$/)/;
return $_;
}
},
HASH => sub {
my($ref,$name) = @_;
return unless defined $ref;
for ("%$name = " . _dump $ref) {
s/= \{/= (/;
s/\}$/)/;
return $_;
}
},
);
Наконец, цикл по множеству разностях между %before
и %after
:
foreach my $name (sort keys %after) {
unless (exists $before{$name}) {
no strict 'refs';
my $glob = $after{$name};
foreach my $slot (keys %dump) {
my $var = $dump{$slot}(*{$glob}{$slot},$name);
print $var, "\n" if defined $var;
}
}
}
Использование my.config
из вашего вопроса, выход
$ ./prog.pl
@A = ('a','b','c')
%B = ('b' => 'bee')
$C = 'see'
Ваш текущий фрагмент кода работает для вас? Если нет, есть ли у вас простой пример файла конфигурации, который вы могли бы разместить? –
@molecules Я добавил образец конфигурации. Это просто очень простой perl. – bukzor
@molecules: Если я правильно ее понимаю, это означает, что я всегда получаю ложные срабатывания для скаляров, но тогда я могу проверить, является ли значение undef, а также я должен все еще правильно определять ARRAY и HASH. – bukzor