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

Hi,
I wish to do something like this -
use strict; use warnings; my %people; my @sentences = ("here i am","i am me"); $people{me}[0] = 0; $people{me}[1] = "1985"; $people{me}[2] = @sentences; @sentences = ("there she is"); $people{friend}[0] = 1; $people{friend}[1] = "1984"; $people{friend}[2] = @sentences; foreach my $person ( %people) { my $rowId = $person[0]; my $dob = $person[1]; addDOBToDatabase($rowId, $dob); foreach my $sentence ( %sentences) { addSentenceToDatabase($rowId, $sentence); } }
but its not working for me since I don't fully understand the concepts involved, what am I doing wrong? Thanks!

Replies are listed 'Best First'.
Re: Help with Hash or Arrays
by biohisham (Priest) on Dec 22, 2009 at 23:16 UTC
    when you tried "$people{me}[2] = @sentences;" you were assigning the number of elements that @sentences has to $people{KEY}[2], noticing that you have updated the @sentences with new values for the other hash key, I did not pass it by reference either, instead I did the assignment as "$people{KEY}[2]= "@sentences""...

    The concept is that the hash keys in this case are array references and hence they need to be treated accordingly, "@{$people{$person}}", this is visible by using the Data::Dumper module ...Here is my take at your post

    #!/usr/local/bin/perl use strict; use warnings; my %people; my @sentences = ("here i am","i am me"); $people{me}[0] = 0; $people{me}[1] = "1985"; $people{me}[2] = "@sentences"; #interpolating... @sentences = ("there she is"); $people{friend}[0] = 1; $people{friend}[1] = "1984"; $people{friend}[2] = "@sentences"; foreach my $person (keys %people){ #each key references an anonymo +us array. my $rowId = $people{$person}->[0]; my $DOB = $people{$person}->[1]; my $sentence = $people{$person}->[2]; addDOBToDatabase($rowId, $DOB); addSentenceToDatabase($rowId, $sentence); } sub addDOBToDatabase{ my @args = @_; print "ID:$args[0], DOB:$args[1]\n"; } sub addSentenceToDatabase{ my @args = @_; print "ID::$args[0], Sentence: $args[1]\n"; } #Viewing data structures can help make decisions on the looping strate +gy... use Data::Dumper; print "\n\UViewing the Data Structure through Data::Dumper:\E\n"; print Dumper(\%people);

    Finally, here is a bunch of links that were very useful to me at clarifying the concept of references, perlref, References quick reference, Referencing in advanced data structures, perldsc and I don't understand hash references...

    Updated:Added links


    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
Re: Help with Hash or Arrays
by NetWallah (Canon) on Dec 22, 2009 at 22:48 UTC
    Using a HOH (Hash-of-hashes) would make this program easier to read and maintain.

    The code below is a guess at what you want to do - I have added parameters I feel would be necessary for your DB handling.

    use strict; use warnings; my %people; my @sentences = ("here i am","i am me"); # Create $people{me} - it contains a HASH-REFERENCE $people{me} = {ROW=>0, DOB=>1985, SPEAK=>[@sentences], # This element is an array-reference, crea +ted from a copy of the array @sentences }; @sentences = ("there she is"); $people{friend} = {ROW=> 1, DOB=> "1984", SPEAK=>[@sentences] # }; foreach my $person (sort keys %people) # Use the KEYS function to get + hash keys, then sort them { addDOBToDatabase( $people{$person}->{ROW}, $person, $people{$person} +->{DOB}); my $sentenceRow = 0; foreach my $sentence ( @{ $people{$person}->{SPEAK} }) # Walk throug +h each element of the array-reference { $sentenceRow++; addSentenceToDatabase( $sentenceRow, $people{$person}->{ROW}, $ +sentence); } }
    You need to understand hashes, and references, to follow this code.

         Theory is when you know something, but it doesn't work.
        Practice is when something works, but you don't know why it works.
        Programmers combine Theory and Practice: Nothing works and they don't know why.         -Anonymous

      With help from Data::Dumper and perltidy, here is how you would normally write that
      my %people = ( 'friend' => { 'SPEAK' => [ 'there she is' ], 'DOB' => '1984', 'ROW' => 1 }, 'me' => { 'SPEAK' => [ 'here i am', 'i am me' ], 'DOB' => 1985, 'ROW' => 0 } );
Re: Help with Hash or Arrays
by Anonymous Monk on Dec 22, 2009 at 22:44 UTC
    Here are some errors you would get if you tried to run that code
    Global symbol "@person" requires explicit package name at foo.pl line +18. Global symbol "@person" requires explicit package name at foo.pl line +19. Global symbol "%sentences" requires explicit package name at foo.pl li +ne 22. Execution of foo.pl aborted due to compilation errors.
    Here is your code fixed up
    use strict; use warnings; my %people; my @sentences = ("here i am","i am me"); $people{me}[0] = 0; $people{me}[1] = "1985"; $people{me}[2] = \@sentences; @sentences = ("there she is"); $people{friend}[0] = 1; $people{friend}[1] = "1984"; $people{friend}[2] = \@sentences; foreach my $person ( values %people) { my $rowId = $$person[0]; my $dob = $$person[1]; my @says = @{$person[2]}; addDOBToDatabase($rowId, $dob); foreach my $sentence ( @says ) { addSentenceToDatabase($rowId, $sentence); } }
    Tutorials: Getting Started with Perl: Data Types and Variables