为什么`存在'修改我的常数?

时间:2010-10-20 09:50:47

标签: perl constants autovivification

exists函数可以unexpectedly autovivify entries加入哈希值。

让我感到惊讶的是,这种行为也会延续到常数:

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表现相似?

2 个答案:

答案 0 :(得分:15)

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

  

即使参考可能是   声明为常量,引用   可能指向可能的数据   如此代码所示,已更改。

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

这是不变的引用,而不是引用它。

答案 1 :(得分:9)

您可能希望使用Readonly来创建“true”常量。

使用constant pragma创建的常量实际上是inlinable subroutines。这意味着在编译时直接插入适当的标量常量来代替某些子程序调用。如果常量是引用,则不会阻止您更改它指向的数据。