【问题标题】:Checking for existence of hash key creates key检查哈希键是否存在创建键
【发布时间】:2012-04-05 01:40:06
【问题描述】:

给定以下代码

#!/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}。这根本不符合逻辑。我所做的只是一个如果存在。我哪里做错了?

【问题讨论】:

    标签: perl hash


    【解决方案1】:

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

    尝试以下方法:

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

    改为

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

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

    【讨论】:

      【解决方案2】:

      Perl 创建它是因为exists 测试指定的最后一个键,它不会递归测试。如果您这样做,则不应创建它:

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

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

      【讨论】:

      • 实际的代码/哈希值更复杂。哈希是:$rotation_hash{output}{oor}{$colo}{$type}{$hostname}{file}{$filename} = 。它是一个实用程序,可以扫描 1000 台主机并创建一份简短的报告,告诉我哪些盒子不旋转。例如,它可能看起来像这样:$rotation_hash{output}{oor}{ac4}{www}{www10.foo.com}{files}{status.html} = 200
      【解决方案3】:

      您已经得到了一些很好的答案,但是,如果您想了解更多关于此行为的信息,它通常称为“自动激活”,如果您希望它不这样做,可以使用 CPAN module 禁用它'不会发生。

      【讨论】:

        【解决方案4】:

        实际的代码/哈希更复杂。哈希是:$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; 的原因相同。当我use strict; 时,Perl 将轻松拾取我在一个地方使用$foobar 作为变量的地方,然后在另一个地方将它称为$fubar。您失去了复杂数据结构的保护。例如,您可能将$rotation_hash{output}{oor} 放在一个地方,但$rotation_hash{oor}{output} 放在另一个地方,use strict 不会捕捉到它。但是,如果您通过package 声明对象,并将子例程用作方法和构造函数,您将获得回报。

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-05-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-30
          • 2013-02-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多