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

Hi all, I want to update a multi-dimensional hash in less lines, and tried to use the slice technique. This works great for a single dimensional hash but i can't seem too do it with a hash of hash. e.g. 1-d hash
%hash = ( Name => 'myname', Number => 'my1234'. Rank => 'myrank', });
updating the hash using a slice:
@hash{"Name", "Number", "Rank"} = ("Kakarot", "3", "SSJ3");
or
my @desc = ("Name", "Number", "Rank"); my @vegeta = ("Vegeta", "2", "SSJ2"); @hash{@desc} = @vegeta;
i'd like to use the slice to add data into a hash of a hash (and depending on the data, a further hash from there onwards). Say, this hash:
my %h = ( Flinstones => { Dad => "Fred", Mom => "Wilma", Kid => "Pebbles", Pet => "Dino" }, Simpsons => { Dad => "Homer", Mom => "Marge", Kid => "Bart", Pet => "Santas_Little_helper" }); my @desc = ("Dad", "Mom", "Kid", "Pet"); @h{TEST =>{@desc}} = ("Mr", "Mrs", "baby", "none"); foreach my $a (keys %h){ print "Key 1 => $a\n"; foreach my $b (keys %{$h{$a}}){ print "\tKey 2 => $b\n"; print "\t\tValue => $h{$a}{$b}\n"; } }
This give me an error in printing, but i'm not sure i'm inserting it right?
(#prints existing data fine but...) Key 1 => TEST Can't use string ("Mr") as a HASH ref while "strict refs" in use at sl +ice_hoh2.pl line
I also tired the referenced approach:
my $href = { Flinstones => { Dad => "Fred", Mom => "Wilma", Kid => "Pebbles", Pet => "Dino" }, Simpsons => { Dad => "Homer", Mom => "Marge", Kid => "Bart", Pet => "Santas_Little_helper" }}; my $desc = ["Dad", "Mom", "Kid", "Pet"]; @{$href->{TEST}->{[@$desc]}} = ("Mr", "Mrs", "baby", "none");
but this has referenced data showing in the output. Not quite sure how it holds up in the hash :s
Key 1 => TEST Can't use string ("Mr") as a HASH ref while "strict refs" in use at sl +ice_hoh2.pl line 35.
Where am i going wrong here?, i can get it done in multiple lines:
$h{TEST}{Dad} = "dad_TEST"; $h{TEST}{Mom} = "mon_TEST"; $h{TEST}{Kid} = "Kid_TEST"; $h{TEST}{Pet} = "pet_TEST";
I'd much rather have slicker looking code :)
Essentially, i'll be reading a file to build my hash of hash. in terms of the example , the data would be the family name followed by the values seperated by tabs, a new 'family' for each line:
Family1 Dad1 Mom1 Kid1 Pet1 Family2 Dad2 Mom2 Kid2 Pet2

Thanks in advance for any help.
Snk1977

Replies are listed 'Best First'.
Re: Slice of Hash of Hash help please
by kyle (Abbot) on Jan 14, 2009 at 18:37 UTC

    The syntax you're looking for is:

    my @desc = ("Dad", "Mom", "Kid", "Pet"); @{$h{TEST}}{@desc} = ("Mr", "Mrs", "baby", "none");

    I learned this by reading References quick reference.

    Here's the whole thing with output:

Re: Slice of Hash of Hash help please
by ikegami (Patriarch) on Jan 14, 2009 at 18:38 UTC

    If it's

    @hash{...} = (...);

    for a hash, it's

    @{$hashref}{...} = (...);

    for a hash ref. Or in this case,

    @{ $h{TEST} }{"Dad", "Mom", "Kid", "Pet"} =("Mr", "Mrs", "baby", "none");

    or

    @{ $h{TEST} }{@desc} = ("Mr", "Mrs", "baby", "none");

    Remember, a hash of hash is really a hash of references to hashes.

      You guys are the best!
      thanks for this :)
      I've spent some time on the tutorials on perl.doc.perl.org and thought i was ok.
      thanks for the link kyle, i'll definately go through this in more detail, and thanks ikegami, i like your examples :)

      thanks again
      Snk1977