Perl 检查哈希键是否存在将创建一个哈希键

Perl 检查哈希键是否存在将创建一个哈希键,perl,hash,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); 我创建了一个空哈希。我有一个数组,里面有一

给定以下代码

#!/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}。这是没有道理的。我所做的只是一个假设。哪里出错了?

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

请尝试以下操作:

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

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

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

Perl创建它是因为
存在
测试指定的最后一个键,而不是递归测试。如果您改为执行以下操作,则不应创建它:

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

然而,你为什么需要额外的钥匙呢?为什么不干脆
$hash{$colo}
?另外,如果您
使用strict
,您将在
$hash

中收到一条关于未初始化值的警告,您已经得到了一些很好的答案,但是,如果您想了解更多有关此行为的信息,通常称为“自动激活”,如果您希望它不会发生,可以使用一个选项来禁用它


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

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

然而,引起我注意的是你的七层杂烩。当您的数据结构开始变得如此复杂时,您应该真正使用Perl面向对象编码。我知道很多人被Perl面向对象编程吓跑了,但是Perl可能是学习OOP最容易的语言之一

如果没有其他原因,那么使用OOP的原因与使用
use strict的原因相同。当我
使用strict时$foobar
作为变量,但在另一个地方将其称为
$fubar
时,Perl将很容易地找到它。使用复杂的数据结构会失去这种保护。例如,您可以将
$rotation\u hash{output}{oor}
放在一个地方,但
$rotation\u hash{oor}{output}
放在另一个地方,而
use strict
不会捕捉到这一点。但是,如果您通过
声明对象,并使用子例程作为方法和构造函数,那么您就可以重新获得它

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


Perl文档中包含了许多优秀的工具。如果您不熟悉OOP Perl,您应该阅读教程并试一试。

实际的代码/哈希更复杂。散列是:$rotation_hash{output}{oor}{$colo}{$type}{$hostname}{file}{$filename}=。这是一个实用程序,可以扫描1000台主机,并创建一个简短的报告,告诉我哪些盒子没有旋转。例如,它可能是这样的:$rotation_hash{output}{oor}{ac4}{www}{www10.foo.com}{files}{status.html}=200