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

urz*_*eit 8 perl constants

我试图use constant在perl中使用值并偶然发现以下奇怪的行为:

#!/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);
Run Code Online (Sandbox Code Playgroud)

将输出

$VAR1 = {
          'a' => 'b'
        };
$VAR1 = {
          'a' => 'b'
        };
Run Code Online (Sandbox Code Playgroud)

常量a被替换的表达式的右侧$d{a} = aa => a左侧,但不是.

我知道常量是使用inlinable subs(这里记录)来实现的,并且子名称如果它们不是预先声明的(这里记录),则评估它们的名称,但我看不出为什么在我的例子中为什么a评估一次值和一次到同一行代码中的名称,特别是在散列的赋值中 - 如果以字母开头,则a => a可能是=>将左侧站点解释为字符串的结果.

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

# ...
my $c = { a() => a }; # or my $c = { a, a };
my %d;
$d{a()} = a;
# ....
Run Code Online (Sandbox Code Playgroud)

输出:

$VAR1 = {
          'b' => 'b'
        };
$VAR1 = {
          'b' => 'b'
        };
Run Code Online (Sandbox Code Playgroud)

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

zdi*_*dim 15

在年底不变页面,在CAVEATS,有答案

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

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

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

然后它也将这个拼出来用于哈希

类似地,由于=>操作员在其左侧立即引用一个裸字,您必须说CONSTANT() => 'value'(或者仅使用逗号代替大箭头)而不是CONSTANT => 'value'.

  • 恭喜达到10k. (3认同)
  • @JonathanLeffler哦,谢谢:)从头开始学习如何做到这一点......体验. (2认同)