为什么我的哈希不是undef?

时间:2010-10-18 10:48:28

标签: perl hash

我在Perl中有以下(从错误中理想化)短脚本:

my %metadata = undef;
if (defined %metadata)
{
    print "defined";
}

由于某种原因,程序的输出始终是“已定义”的。因此,将哈希值设置为“未定义”会使其定义。是否定义为“未定义”?

编辑:

这是一个理想化的案例,试图复制问题。我实际上做的更像是:

my %metadata = my_sub_function();
if (defined %metadata)
{
    print "defined";
}

my_sub_function的输出可能是undef,()或填充的哈希,我只想在最后一种情况下打印“已定义”。

编辑2:

顺便说一句,我发现了

if (scalar(keys %metadata)

对于()表现正确,但仍然不适用于undef。

4 个答案:

答案 0 :(得分:8)

尝试

 my %metadata;
 undef %metadata;
 if (defined %metadata)
 {
     print "defined";
 }

我认为只是使用“undef”作为填充哈希的数据。

“使用警告”会说:

defined(%hash) is deprecated at t.pl line 6.
    (Maybe you should just omit the defined()?)
Odd number of elements in hash assignment at t.pl line 4.
Use of uninitialized value in list assignment at t.pl line 4.
  

undef,()或填充的哈希

如果你真的想要区分空哈希和没有哈希,那么最好使用哈希引用(也可以更轻松地从子程序传递,没有副本和所有)。

答案 1 :(得分:8)

如果您的函数返回undef并且undef放在哈希中,则自动字符串化会将undef更改为'',最后会得到:%metadata = ( '' => undef )

如果你的函数需要返回undef()或正确的哈希,你需要分别测试所有三种情况,我建议:

my %metadata = my_sub_function();
if ( !scalar keys %metadata ) {
  print "An empty list () was returned\n"
} elsif (
  scalar keys %metadata == 1 and
  exists $metadata{''} and
  !defined $metadata{''}
) {
  print "undef or '' was returned\n";
} else {
  print "A hash was hopefully returned\n";
}

您可以使用以下my_sub_functions测试它:

sub my_sub_function { return ()                 } # 1st case
sub my_sub_function { return undef              } # 2nd case
sub my_sub_function { return ( a => 1, b => 2 ) } # 3rd case
sub my_sub_function { return qw/not a hash/     } # unhandled case

快乐的黑客攻击

答案 2 :(得分:2)

如果您看到defined的文档,您会发现

When defined used on a hash element, 
it tells you whether the value is defined, 
not whether the key exists in the hash. 

尝试简单,if (%a_hash) { print "has hash members\n" }

注意:undef是从未初始化(或已使用undef函数重置的变量)的值。 The defined function returns true if the value of the expression is not undef.

答案 3 :(得分:1)

试试这个

%metadata=("1"=>"one");
undef %metadata;
if ( %metadata)
{
    print "defined";
}

如果您查看perldoc -f defined上的文档,它会说这种检查方式已被弃用。

 Use of "defined" on aggregates (hashes and arrays) is deprecated.