开发者

Why is `exists` modifying my constant?

开发者 https://www.devze.com 2023-01-21 16:22 出处:网络
The exists function can unexpectedly autovivify entries in hashes. What surprises me is that this behavior carries over to constants as well:

The exists function can unexpectedly autovivify entries in hashes.

What surprises me is that this behavior carries over to constants as well:

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

use constant data => {
                       'foo' => {
                                  'bar' => 'baz',
                                },
                       'a'   => {
          开发者_JAVA技巧                        '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

Output

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

I suspect this is a bug. Is this something 5.10.1-specific, or do other versions of Perl behave similarly?


This is documented behaviour. perldoc constant says:

Even though a reference may be declared as a constant, the reference may point to data which may be changed, as this code shows.

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

It's the reference that is constant, not what it refers to.


You probably want to use Readonly for creating "true" constants.

Constants created using the constant pragma are actually inlinable subroutines. It means that at compile time the appropriate scalar constant is inserted directly in place of some subroutine call. If the constant is a reference, nothing prevents you from changing the data it points to.

0

精彩评论

暂无评论...
验证码 换一张
取 消