Perl - Hash和=>操作者

时间:2015-06-18 22:08:01

标签: perl hash

所以我正在学习Perl并进入关于哈希的章节。我明白'=>' operator是逗号运算符的别名。但是当我尝试设置值 undef 时,我会收到警告

在连接(。)中使用未初始化的值$ last_name {“dino”}或在./learning.pl第18行使用字符串。

use warnings;
use strict;

my %last_name = (
    fred   => 'flintston',
    dino   =>  undef,
    barney => 'rubble',
    betty  => 'rubble',
);

my $key;
my $value;

if(%last_name) {
    foreach $key (sort keys %last_name) {
        print("$key => $last_name{$key}\n");
    }
}

但是当我将哈希线更改为:

my %last_name = (
    fred   => 'flintston',
    dino   =>  undef =>
    barney => 'rubble',
    betty  => 'rubble',
);

它工作得很好,并将值返回为undef。我所做的只是替换使用'=>'分隔键/值的逗号运算符运营商。

如果两个运算符应该是相同的,为什么后面的工作而不是前者?

2 个答案:

答案 0 :(得分:11)

它们并不完全相同。 “胖逗号”还做了一件事:当它是一个单词时,它会引用左侧操作数。因此,

undef, 1

相当于

undef(), 1

,而

undef => 1

相当于

'undef', 1

请参阅perlop

  

=> operator是逗号的同义词,除非它使左侧的单词被解释为字符串(如果它以字母或下划线开头)并且仅由字母,数字和下划线组成。

答案 1 :(得分:7)

Choroba已经回答了,但我认为稍微扩展一下会很有用。

在第一种情况下,当您收到警告时,因为您正在打印undef值:键'dino'的值未定义。请注意,当您设置哈希值时,您不会收到任何警告,因为为键提供未定义的值是完全正常的。仅当您尝试使用此未定义值时,警告才会显示;最好在使用前检查它,如下所示:

if (defined $last_name{$key}) {
    print("$key => $last_name{$key}\n");
}

这样你可以避免警告。

有趣的部分出现在你的第二个案例中。要了解会发生什么,您可以在最后运行此代码:

if (defined $last_name{'dino'}) {
    print "last_name{'dino'} is defined, and its value is $last_name{'dino'}\n";
    if ($last_name{'dino'} =~ /^[u][n][d][e][f]$/) {
        print "It matches, which means that the value of last_name{'dino'} " .
              "is not undefined, it's the string 'undef'\n";
    }
}

并且if都为真,这表示$last_name{'dino'} 的值已定义,并且它是字符串' undef' 。当然它令人困惑,但它是定义的。因此,您不会收到任何警告。

所有这些都是查看正在发生什么的方法。要了解为什么,请查看choroba的答案。