Perl 为什么我的哈希不是未定义的?

Perl 为什么我的哈希不是未定义的?,perl,hash,Perl,Hash,我用Perl编写了以下(源于一个bug的理想化)简短脚本: my %metadata = undef; if (defined %metadata) { print "defined"; } 由于某种原因,程序的输出总是“定义的”。因此,将哈希设置为“未定义”会使它被定义。是否定义为“未定义” 编辑: 这是一个理想化的案例,试图复制这个问题。我实际上做的更像是: my %metadata = my_sub_function(); if (defined %metadata) {

我用Perl编写了以下(源于一个bug的理想化)简短脚本:

my %metadata = undef;
if (defined %metadata)
{
    print "defined";
}
由于某种原因,程序的输出总是“定义的”。因此,将哈希设置为“未定义”会使它被定义。是否定义为“未定义”

编辑:

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

my %metadata = my_sub_function();
if (defined %metadata)
{
    print "defined";
}
其中,my_sub_函数的输出可能是undef、()或填充的哈希,我只想在最后一种情况下打印“defined”

编辑2:

顺便说一句,我发现

if (scalar(keys %metadata)
对于()的行为正确,但对于undef仍然不正确。

请尝试

 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.
未定义,()或填充的哈希

如果您真的想区分空哈希和无哈希,最好使用哈希引用(也可以从子例程传递、无传递副本和全部)。

试试这个

%metadata=("1"=>"one");
undef %metadata;
if ( %metadata)
{
    print "defined";
}
如果你看一下
perldoc-f defined
上的文档,就会发现这种检查方法是不推荐的

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

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

When defined used on a hash element, 
it tells you whether the value is defined, 
not whether the key exists in the hash. 
如果(%a_hash){print“有散列成员,\n”}


注意:
undef
是从未初始化(或使用函数重置)的变量值
如果表达式的值不是未定义的,则定义的函数返回true。

如果函数返回
undef
,并且未定义被放置在散列中,则自动字符串化会将未定义更改为
'
,最终结果是:
%metadata=('=>undef)

如果您的函数需要返回
unde
()
或适当的散列,并且需要分别测试这三种情况,我建议:

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_函数对其进行测试:

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

快乐黑客

啊,有趣!我在我的日志中没有看到这个错误,它产生的代码确实使用了strict和warnings。我也尝试过不使用defined(%hash),但结果相同。不幸的是,我不负责直接从子函数返回的内容,因此我必须使用所给的内容:)“使用defined on aggregates(hash和array)已弃用。它用于报告是否为该聚合分配了内存。这种行为可能会在未来的Perl版本中消失。您应该改为使用简单的“大小测试”。因此,您当前的方法可能不太有效。最好与制作该子例程的人谈谈。
my_sub_函数
是否执行
returnundef
以指示失败或无数据?如果是这样,它可能应该执行一个简单的
返回。这将在标量上下文中被解释为
unde
,在列表上下文中被解释为
()
(空列表);非常感谢!Perl总是让我意识到它使一些困难的事情变得多么容易,而一些本来应该简单的事情变得多么困难:)