nickandrew has asked for the wisdom of the Perl Monks concerning the following question:

O wise perl monks,
please grant me the benefit of your advice:

Investigating a bizarre problem today, I found some anomalous behaviour in perl.

use Data::Dumper qw(Dumper); my $data = { args => '', }; $data->{args}->{stuff} = 'bother'; print Dumper($data); print "The value is ", $data->{args}->{stuff}, "\n";

The script outputs:

$VAR1 = { 'args' => '' }; The value is bother

Now, "$data->{args}" has been initialised to a scalar empty string. Without using "use strict", perl allows code which treats this like a hashref and stores something in it. The stored data (in this case, a hashref with key stuff and value bother) can't be seen by Data::Dumper but can be retrieved in the same way it was stored.

Is this a perl bug? If I "use strict" then my program emits an error.

Is this a language feature? I have checked this behaviour in perl 5.6, 5.8 and 5.10. Is it something to do with symbolic references ala "use strict refs" ?

Replies are listed 'Best First'.
Re: The hidden hashref
by moritz (Cardinal) on May 19, 2010 at 13:10 UTC
    If I "use strict" then my program emits an error.
    Which is pretty informative, so don't ignore it:
    Can't use string ("") as a HASH ref while "strict refs" in use at foo. +pl line 8.

    What this tells you is: you've used a symbolic reference, and it's name is the empty string. You can also retrieve it with the empty string as name.

    But the things that's stored in the hash is still an empty string, and Data::Dumper reports it as such.

    (The symbolic reference is resolved via the symbol table, not via the hash, which is why you don't see any references to 'bother" in the output).

    I find unintended symbolic references rather confusing, which is why I always use strict;.

Re: The hidden hashref
by almut (Canon) on May 19, 2010 at 13:39 UTC
    print "The value is ", $data->{args}->{stuff}, "\n";

    Other ways to write this — which should clarify what's going on:

    print "The value is ", $::{''}->{stuff}, "\n"; print "The value is ", $::{$data->{args}}->{stuff}, "\n";

    (all three print "The value is bother")

Re: The hidden hashref
by GrandFather (Saint) on May 19, 2010 at 21:33 UTC

    It's either a bug of a feature in your code depending on your intent. Perl allows the use of symbolic references in that fashion unless you use strict as you found. Symbolic references are generally considered evil and there are almost always other ways of achieving the same effect.

    So, yes it is a feature of Perl. It does have to do with "use strict refs". Symbolic references are generally a good thing to avoid and strict is always a good thing to use by default.

    True laziness is hard work