perl使用未定义的值分配键

时间:2015-11-25 06:19:23

标签: perl hashtable

我有一段代码看起来像这样:

$deepest{$xval} = $Evalue unless exists $deepest{$xval}; 

#some code

foreach (keys %deepest){
  print $datfh $_, "\t", $deepest{$_}, "\n";
}

然后我将其改为

$deepest{$xval} = [$Evalue, $id] unless exists $deepest{$xval}[0];

#some more code

foreach (keys %deepest){
  print $datfh $_, "\t", $deepest{$_}[0], "\t", $deepest{$_}[1], "\n";
}

现在我得到了,当我打印哈希后,发出很多警告:

Use of uninitialized value in print

我之前没有得到过。

为什么新的哈希结构与旧的哈希结构不同?我有什么办法可以避免未初始化的条目吗?

更新:愚蠢的我,我没有包含在原始问题中实际导致错误的部分代码。现在它已经进入,现在我也知道如何摆脱它,即用exists $deepest{$xval}[0]替换exists $deepest{$xval},不知何故第一种方式创建了哈希条目。

2 个答案:

答案 0 :(得分:1)

试试这段代码

#should check exists of hash, not array
$deepest{$xval} = [$Evalue, $id] unless exists $deepest{$xval};
# some code
foreach (keys %deepest){
  # its good practice to use -> for arrayrefs and hashrefs ($deepest{$_} - arrayref)
  #and you should check $deepest{$xval}->[1] ( $id ) , maybe $id is undef
  warn '$id is not defined ' unless defined $deepest{$_}->[1];
  print $datfh $_, "\t", $deepest{$_}->[0], "\t", $deepest{$_}->[1],    "\n";
}

答案 1 :(得分:1)

存在测试密钥是否存在的测试。这很有用,但它可能不完全是您想要的,因为如果该键的是undef,它就可以工作。

您可能会发现defined符合您的要求:

my %hash = ( key => undef ); 

print "Key exists\n" if exists $hash{$key};
print "Key defined\n" if defined $hash{$key}; 

在你的情况下:

my %hash = ( key => [ ] ); 
print "Exists\n" if exists $hash{key};
print "Defined\n" if defined $hash{key}; 
print "Is true\n" if $hash{key}; 
print "Has values\n" if @{$hash{key}};

但是看看你的代码,我的想法是 - 你插入的匿名数组 - 确实总是至少有两个(已定义的)元素吗?

因为你能解决这个问题的一个显而易见的方法是:

my %hash = ( key => [ "value", undef ] ); 
print $hash{key}[0], $hash{key}[1],"\n";

关于解除引用(因为它对于评论来说有点太大) - 实际上只需要取消引用一次。

由于:

my $array_ref = [ 1, 4, 9 ]; 
print $array_ref,"\n"; #scalar value; 
print $array_ref -> [0],"\n"; #also scalar, from within array. 

但是如果你有:

my @array = ( [1, 4, 9], 
              [16, 25, 36], );
print "@array\n";
print \@array,"\n";
print $array[0],"\n"; #reference scalar - but because of the brackets
                      #perl knows you're referring to @array. 
print $array[0][1],"\n"; #scalar, but implicitly dereferenced.
print $array[0]->[1]; #dereferenced scalar, same as above.

最后两个案例是一样的 - 为什么?好吧,因为它必须。 'parent'数组必须是一个引用,因为这是一个数组数组的工作方式,因此perl可以自动解除引用。