in reply to Extending a hash

$hash{a} may either valuate to a scalar or an array reference but not both, at least not in the way you present - Perl is trying to interpret bob as an array reference and bombing out with a slightly confusing error message. I would tend to make it always valuate to an array reference, even if there is only one value, e.g.
use strict; use warnings; my $cfg = ARGV[0] or die "Usage: $0 <config_file>\n"; my %hash; open my $ch, $cfg or die "$!: $cfg\n"; while( <$ch> ) { chomp; my ($k, $v) = split /\s+/; $hash{k} ||= []; push @{ $hash{$k}}, $v; } close $ch;

One world, one people

Replies are listed 'Best First'.
Re^2: Extending a hash
by bart (Canon) on Apr 21, 2011 at 11:26 UTC
    Perl is trying to interpret bob as an array reference and bombing out with a slightly confusing error message.
    I must disagree, I don't think it is confusing, once you understand what's going on.

    Perl has a feature to use symbolic references, i.e. a variable may contain the name of a global variable and you can access its contents through it. For example:

    our $red = 10; our $green = 6; my $apples = 'red'; $$apples--; # eat an apple print "I've got $red red apples, and $green green ones.\n";
    Result:
    I've got 9 red apples, and 6 green ones.

    It's a powerful system but abusing it is not a good idea. That's why strict prevents it by default (when you use strict;).

    What is the source of the confusion here, is that the syntax (and the code for the internals) is the same as with real references instead of strings.

    It also works with hashes and arrays for data, and with any kind of scalar as the symbolic reference. And that is what is going on here: $hash{a} contains the string 'bob' so $hash{a}[0] is trying to either use $hash{a} as an array reference (if it is a reference; or undef, which is what we usually want anyway) or, since it is a string here, as a symbolic reference to the global variable @bob. And the latter is what strict is preventing, with that error message as a result

    Try it with no strict:

    our @bob; my %hash; $hash{a} = 'bob'; $hash{a}[0] = 1; print "\@bob contains: [@bob]\n";
    which results in
    @bob contains: [1]
Re^2: Extending a hash
by anonymized user 468275 (Curate) on Apr 21, 2011 at 11:32 UTC
    Yes, I used the word "slightly" to bridge the gap between my understanding the OP's stated perspective - the confusion is obviously not mine. There is really no need for such a lecture. What is it about this site that attracts so many straw man arguments? I made an honest suggestion to help the OP. So why are you entering into a discourse on techniques you don't even encourage?

    One world, one people