Search code examples
perlconstantsautovivification

Why is `exists` modifying my constant?


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'   => {
                                  '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?


Solution

  • 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.