如何在没有任何键/值对时检查是否定义了Perl哈希

时间:2011-07-26 23:58:28

标签: perl hash

更新注意:我已修改此问题,希望以更好的方式提出问题。最初,我有更多的代码试图证明我的目标,但它只是阻碍了。另外,我正在引用“已定义”。事实证明,事实并非如此。更新后的问题应该澄清我正在尝试做什么。


我正试图找出一种方法来检查在模块函数内部是否已在perl脚本中声明了哈希。

给出以下脚本(script.pl):

#!/usr/bin/perl -w

use strict; 
use checkHash;

our %testHash = ("key"=>"value");

print &checkHash() ? 1 : 0;

与此模块一起(checkHash.pm);

sub checkHash { 
    if(%main::testHash) { 
        return 1; 
    }
    else { 
        return 0; 
    }
}

1;

在OS X 10.6.7和perl v5.10.0的Mac上运行,checkHash的返回值为“1”,这是我所期望的。但是,如果我通过更改行来删除脚本中的键值对:

our %testHash = ("key"=>"value");

为:

our %testHash = ();

返回值为“0”。我最初的假设是这将是“1”,但在阅读了我正在使用的测试方法测试散列中的大小之后,我明白为什么这是错误的思考。

我的问题是:

是否有一个可以在checkHash模块中使用的测试,如果测试的哈希存在但是没有分配任何密钥,它将返回true?

4 个答案:

答案 0 :(得分:4)

defined()对聚合(数组和散列)不是一个有意义的测试。 perldoc -f defined有这样的说法:

  

不推荐在聚合(哈希和数组)上使用“已定义”。它   用于报告该聚合的内存是否曾经存在过   分配。                  在将来的Perl版本中,此行为可能会消失。   您应该使用简单的大小测试:

               if (@an_array) { print "has array elements\n" }
               if (%a_hash)   { print "has hash members\n"   }

答案 1 :(得分:4)

测试是否已声明给定符号几乎肯定是无用的,并且执行它的愿望表明存在设计问题。然而,为了完整起见,这里是对词法和动态符号的测试:

查明是否已声明词汇符号$whoopee

use Try::Tiny;
my $declared = try { use strict; $whoopee; 1 };

找出是否已声明任何名为FooPackage::whoopee的动态符号(包括拼写其名称%FooPackage::whoopee的哈希):

my $declared = exists $FooPackage::{whoopee};

答案 2 :(得分:1)

你可以算一下按键:

sub checkHash {
    return ( scalar keys %main::testHash ) ? 1 : 0;
}

perl -le 'my %h; print ( scalar keys %h ) ? 1 : 0;'
0
perl -le 'my %h = (foo=>1); print ( scalar keys %h ) ? 1 : 0;'
1

答案 3 :(得分:1)

请参阅perldoc perldata

  

如果在标量上下文中评估散列,则在散列为空时返回false。如果有任何键/值对,则返回true;更确切地说,返回的值是一个字符串,由使用的桶数和分配的桶数组成,用斜杠分隔。

这解释了为什么您的defined测试似乎有效。