检查是否存在哈希密钥创建密钥

时间:2012-03-20 15:04:15

标签: perl hash

给出以下代码

#!/usr/bin/perl

use Data::Dumper;

my %hash;
my @colos = qw(ac4 ch1 ir2 ird kr3);

foreach my $colo (@colos) {
    if(exists $hash{output}{$colo}) {
        print "$colo is in the hash\n";
    }
}

print Dumper(\%hash);

我创建了一个空哈希。我有一个数组,里面有几个缩写。如果我遍历数组以查看这些人是否在哈希中,则没有任何内容显示给STDOUT,这是预期的但是由于某种原因创建了$ hash {output}。这根本不符合逻辑。我所做的只是存在。我哪里出错了?

4 个答案:

答案 0 :(得分:7)

exists查找给定哈希中的哈希元素。您的代码自动生成散列
 %{ $hash{output} }并检查该哈希中是否存在密钥为$colo的哈希元素。

尝试以下方法:

if(exists $hash{output}{$colo}) {

更改为

if(exists $hash{output} and exists $hash{output}{$colo}) {

当然,您可以编写一个隐藏代码复杂性的子代码。

答案 1 :(得分:3)

Perl创建它,因为exists测试指定的最后一个键,它不会递归测试。如果您改为:

,则不应该创建它
if( exists $hash{output} && exists $hash{output}{$colo} ) {

但是为什么你还需要额外的钥匙呢?为什么不只是$hash{$colo}?此外,如果您use strict,则会在$hash中收到有关未初始化值的警告。

答案 2 :(得分:3)

你已经有了一些很好的答案,但是,如果你想了解更多关于这种行为的信息,它通常被称为“autovivification”,并且有一个CPAN module可以禁用它,如果你愿意的话不会发生。

答案 3 :(得分:1)

  

实际的代码/哈希更复杂。哈希是:$ rotation_hash {output} {oor} {$ colo} {$ type} {$ hostname} {file} {$ filename} =< html_status_code>

正如其他人所说,当您询问是否存在$foo{bar}{fubar}时,Perl会自动创建$foo{bar}以测试$foo{bar}{fubar}是否存在。如果您想阻止这种情况,则必须进行测试以查看$foo{bar}是否存在,如果存在,则测试$foo{bar}{fubar}是否存在。

然而,引起我注意的是你的七层哈希。当您的数据结构开始变得复杂时,您应该真正使用Perl面向对象的编码。我知道很多人都被Perl反对的导向编程所吓倒,但Perl可能是人们获取OOP最简单的语言之一。

如果没有别的,您使用OOP的原因与使用use strict;的原因相同。当我use strict;时,Perl会轻松拾取我在一个地方使用$foobar作为变量的位置,但在其他地方将其称为$fubar。您会因复杂的数据结构而失去保护。例如,您可以将$rotation_hash{output}{oor}放在一个位置,但$rotation_hash{oor}{output}放在另一个位置,而use strict则无法捕捉到它。但是,如果你通过package声明对象,并使用子程序作为方法和构造函数,那么你可以获得它。

面向对象的设计还可以帮助您消除跟踪数据结构的需要。对象为您处理这些,您可以专注于编码。而且,您不必创建多个文件。您只需将对象定义附加到文件的底部即可。

Perl文档中包含some个优秀tutorials。如果你不熟悉OOP Perl,你应该仔细阅读教程并尝试一下。