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

Need a little help to expand my understanding of somewhat complex data structures.
use strict; my $hash_ref = { key1 => "value1", key2 => "value2", ary1 => [ { ary_key01 => "ary_value01", ary_key02 => "ary_value02", }, { ary_key11 => "ary_value11", ary_key12 => "ary_value12", }, ], };
Given the above, I now wish to add (or edit) some values. For that I use this working solution.
$hash_ref -> { key1 } = "new value1"; $hash_ref -> { key3 } = "add value3"; $hash_ref -> { ary1 }[2] = { ary_key21 => "ary_value21", ary_key22 => +"ary_value22", }; use Data::Dumper; print Dumper($hash_ref); exit;
What I do not understand is how to make the above work with some sort of a data structure. Kind of like this..
$hash_ref -> { key1 => "new value1", key3 => "add value3", ary1[2] => [{ ary_key21 => "ary_value21", ary_key22 => "ary_value2 +2", }], };
Which gives errors:
Can't use subscript on constant item at test.cgi line 15, near "2]"
Can't use bareword ("ary1") as an ARRAY ref while "strict refs" in use at test.cgi line 15.

Can I do what I'm asking or should I stay with my initial approach?. A seach of PM and Perl Cookbook was little help.

Replies are listed 'Best First'.
Re: Add values to a referenced HoH
by ikegami (Patriarch) on Apr 27, 2005 at 22:04 UTC

    You can't do that. Like friedo mentioned, you can add more than one item to a hash at a time using hash slices. You can also add more than one item to an array at a time using array slices (which he didn't show). But that's it. You can't add to a hash and to a structure referenced by an element of that hash at the same time.

    You say you don't understand why it isn't allowed, so let me explain. Any valid Perl expression (or barewords when using =>) can be used where a hash key is expected. If they allowed fancy expressions like arr1[2], Perl would have to be changed to not allow Perl expressions where hash keys are expected, since it wouldn't know which parsing rules to use. That would disallow $hash{uc{$key}} = $value, for example, and that would be bad.

    Not only would Perl incur a great loss of commonly used functionality, the only benefit is a small potential improvement in readability. I personally think it reduces readability because it creates a method for making assignments that doesn't use the assignment operator. You're trying to treat => as an assignment operator, but => can actually be used anywhere , is used. The arrow is pointing in the wrong direction for an assignment operator anyway.

    By the way,

    $hash_ref->{ key1 => "new value1", key3 => "add value3" }

    means

    $hash_ref->{join($;, 'key1', "new value1", 'key3', "add value3")}

    It will give you the warning "Useless use of hash element in void context" unless you assign a value to it, or assign it to a variable.

Re: Add values to a referenced HoH
by friedo (Prior) on Apr 27, 2005 at 21:51 UTC
    It looks like you want to assign to a slice of the hash-ref. That will take care of assigning the scalars to key1 and key3. For the array, you can use push. This should work:

    @{$hash_ref}{qw(key1 key3)} = ( "new value1", "add value3" ); push @{$hash_ref->{ary1}}, { ary_key21 => "ary_value21", ary_key22 => "ary_value22", };