2010-10-18 104 views
5

我有以下的(从错误理想化的)短Perl脚本:为什么我的哈希不是undef?

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

出于某种原因,该程序的输出总是“定义”。因此,将哈希设置为“未定义”会以某种方式使其定义。它被定义为“未定义”吗?

编辑:

这是一种理想化的情况下,企图复制的问题。什么我实际上做的更像是:

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

凡my_sub_function的输出可能是民主基金,()或填充乱码,我只希望在最后的这些情况下打印“定义”。

编辑2:

顺便说一句我发现

if (scalar(keys %metadata) 

行为正确的(),但仍然不是民主基金。

+3

不'my_sub_function'做了'回undef'给我ndicate失败或没有数据?如果是这样,它可能应该做一个简单的'返回'而不是。这将被解释为标量上下文中的“undef”和列表上下文中的“()”(空列表)。 – 2010-10-18 13:13:23

回答

8

如果你的函数返回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 

快乐黑客

+1

精彩;非常感谢! Perl总是让我感到困难是多么的容易,有些事情应该是简单的:) – 2010-10-18 14:21:28

8

尝试

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

我认为它只是用“民主基金”的数据来填充哈希。

“使用警告”会说:

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. 

民主基金,()或填充的哈希

如果你真的想要一个空的哈希和没有哈希区分,更好使用散列引用(也可以使用较轻的来自子例程,不传递所有副本)。

+0

啊,有意思!我在日志中没有看到这个错误,并且它的代码使用严格并使用警告。我也尝试过没有定义(%散列),虽然有相同的结果。 – 2010-10-18 10:57:05

+0

不幸的是,我并不负责直接从子函数返回的内容,所以我必须使用我提供的内容:) – 2010-10-18 11:00:44

+0

“不再使用定义在聚合(哈希和数组)上的方法。它用于报告是否曾经分配过该聚集的内存,这种行为在未来的Perl版本中可能会消失,您应该使用简单的大小测试“。所以,你现在的做法可能不太好。更好地与制作该子程序的人交谈。 – Thilo 2010-10-18 11:06:37

1

试试这个

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

如果你看一下在perldoc -f defined的文档,它说,检查的方式这个不推荐使用。

Use of "defined" on aggregates (hashes and arrays) is deprecated. 
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.

相关问题