更新注意:我已修改此问题,希望以更好的方式提出问题。最初,我有更多的代码试图证明我的目标,但它只是阻碍了。另外,我正在引用“已定义”。事实证明,事实并非如此。更新后的问题应该澄清我正在尝试做什么。
我正试图找出一种方法来检查在模块函数内部是否已在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?
答案 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)
如果在标量上下文中评估散列,则在散列为空时返回false。如果有任何键/值对,则返回true;更确切地说,返回的值是一个字符串,由使用的桶数和分配的桶数组成,用斜杠分隔。
这解释了为什么您的defined
测试似乎有效。