perl常量在哪里被它们的值替换?

时间:2016-12-12 05:46:45

标签: perl constants

我在perl中尝试了use constant个值并偶然发现了以下奇怪的行为:

#!/usr/bin/perl
use strict;
use warnings;

use Data::Dumper;

use constant {
    a => "b"
};

my $c = { a => a };
my %d;
$d{a} = a;

print Dumper($c);
print Dumper(\%d);

将输出

$VAR1 = {
          'a' => 'b'
        };
$VAR1 = {
          'a' => 'b'
        };

常量a已替换在表达式$d{a} = aa => a的右侧,但不在左侧。

我知道常量是使用inlinable subs(documented here)实现的,如果子名称不是预先声明的(documented here),那么子名称会评估它们的名称,但我看不出有什么理由在我的示例a对值进行一次计算,对同一行代码中的名称进行一次计算,尤其是对哈希的赋值 - a => a可能是=>解释左边的结果如果网站以字母开头,则为网址。

旁注:添加parantheses以使子调用显式化会产生预期结果:

# ...
my $c = { a() => a }; # or my $c = { a, a };
my %d;
$d{a()} = a;
# ....

输出:

$VAR1 = {
          'b' => 'b'
        };
$VAR1 = {
          'b' => 'b'
        };

(所有使用perl 5.18测试的例子)

1 个答案:

答案 0 :(得分:15)

constant页面的末尾CAVEATS有答案

  

如果在自动引用裸字的上下文中使用常量,则可能会遇到麻烦(对于任何子例程调用都是如此)。例如,您不能说$hash{CONSTANT}因为CONSTANT将被解释为字符串。

然后继续您找到的解决方案

  

使用$hash{CONSTANT()}$hash{+CONSTANT}来防止裸字引用机制被踢入。

然后它也为哈希拼写出来

  

同样,由于=>运算符会在其左侧立即引用一个裸字,因此您必须说CONSTANT() => 'value'(或仅使用逗号代替大箭头)而不是CONSTANT => 'value'