以下代码通过提供此警告消息让我困惑了一段时间:Use of uninitialized value in join or string at ./mycode.pl line 666.
其中第666行:print "@{n0->{$x}{$y}}\n";
。请注意,n
是字符串数组的哈希哈希,如下所示:
n = (
x0 => {
y0 => [ "foo00", "bar00" ]
y1 => [ "foo01", "bar01" ]
...
}
x1 => {
y0 => [ "foo10", "bar10" ]
y1 => [ "foo11", "bar11" ]
...
}
...
)
以下是代码:
my $rn =\%n;
for my $x (keys %$rn){
print "$x\n";
for my $y (keys %{$rn->{$x}}){
print "@{$rn->{$x}{$y}}\n";
}
}
我不明白为什么Perl会抱怨uninitialized values
。从本质上讲,我预计元素必须具有值,否则它们甚至不会存在,因此不会出现在迭代中。而且,输出符合我的预期。
我在这里失踪的关键是什么?我怎么能摆脱它?
答案 0 :(得分:0)
以下代码有效;看看你的代码有什么不同。
use strict;
use warnings;
my %n = (
x0 => {
y0 => [ "foo00", "bar00" ],
y1 => [ "foo01", "bar01" ]
},
x1 => {
y0 => [ "foo10", "bar10" ],
y1 => [ "foo11", "bar11" ]
}
);
my $rn =\%n;
for my $x (keys %$rn){
print "$x\n";
for my $y (keys %{$rn->{$x}}){
print "@{$rn->{$x}{$y}}\n";
}
}
也许您的数据并不完全符合您的想法?
添加use Data::Dumper; print Data::Dumper->new([$rn])->Useqq(1)->Terse(1)->Dump;
并查看是否有任何线索为您提供了线索。
您可以通过在打印之前放置它来跟踪特别是触发警告的值:
local $SIG{__WARN__} = sub { print "warning given when x is $x and y is $y: ", @_ };
那就是说,除非其中一个数组元素未定义,否则除非我将$"
设置为undef,否则我无法发出警告(尽管您使用的是perl的古老版本和我不是,所以这可能会产生影响。)如果实际上你正在改变$"
(通常是空格字符),你应该避免在字符串中插入一个数组,而是明确地做:
print join(" ", @{$rn->{$x}{$y}}), "\n";
答案 1 :(得分:0)
乍一看,您的代码似乎没有任何问题。因此,您的数据存在争议。
我建议使用Data::Dump
(我的偏好)或Data::Dumper
等模块来检查您的数据。然后,您可以更容易地确定哪个密钥具有错误数据,但具有哪个值。
如果你想要花哨,你甚至可以创建一个特殊的$SIG{__WARN__}
处理程序,只有在发现错误时才输出附加信息。
use strict;
use warnings;
my %n = (
x0 => {
y0 => [ "foo00", "bar00" ],
y1 => [ "foo01", "bar01" ],
},
x1 => {
y0 => [ "foo10", undef ],
y1 => [ "foo11", "bar11" ],
},
);
my $rn = \%n;
for my $x ( keys %$rn ) {
print "$x\n";
for my $y ( keys %{ $rn->{$x} } ) {
# Catch Warning and output additional info
local $SIG{__WARN__} = sub {
warn @_; # Output regular warning info
use Data::Dump;
dd $x, $y, $rn->{$x}{$y};
};
print "@{$rn->{$x}{$y}}\n";
}
}
输出:
x1
foo11 bar11
Use of uninitialized value in join or string at b.pl line 24.
("x1", "y0", ["foo10", undef])
foo10
x0
foo01 bar01
foo00 bar00