7

exists函数可能会意外地自动激活哈希中的条目。

令我惊讶的是,这种行为也延续到常量:

use strict;
use warnings;
use Data::Dump 'dump';

use constant data => {
                       'foo' => {
                                  'bar' => 'baz',
                                },
                       'a'   => {
                                  'b'   => 'c',
                                }
                     };

dump data;   # Pre-modified

print "No data for 'soda->cola->pop'\n" unless exists data->{soda}{cola}{pop};

dump data;   # data->{soda}{cola} now sprung to life

输出

{ a => { b => "c" }, foo => { bar => "baz" } }
No data for 'soda->cola->pop'
{ a => { b => "c" }, foo => { bar => "baz" }, soda => { cola => {} } }

我怀疑这是一个错误。这是 5.10.1 特有的,还是其他版本的 Perl 表现类似?

4

2 回答 2

16

这是记录在案的行为。perldoc 常数说:

即使可以将引用声明为常量,该引用也可能指向可能更改的数据,如此代码所示。

use constant ARRAY => [ 1,2,3,4 ];
print ARRAY->[1];
ARRAY->[1] = " be changed";
print ARRAY->[1];

它是恒定的引用,而不是它所指的内容。

于 2010-10-20T10:03:00.877 回答
9

您可能想使用Readonly来创建“真正的”常量。

使用constantpragma 创建的常量实际上是可内联的子例程。这意味着在编译时直接插入适当的标量常量来代替某些子例程调用。如果常量是一个引用,那么没有什么可以阻止您更改它指向的数据。

于 2010-10-20T10:00:50.070 回答