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

Hi all, Im learning perl and i start reading the book "beginning perl curtis ovid poe" and i stop at the chapter 6 EXERCISES on second task. The task is: "Write the code to find the individual number of sales Jim made on Friday and the total number of the sales he made on Friday. Assume each number is the total for an individual sale."

my $sales = { monday => { jim => [ 2 ], mary => [ 1, 3, 7 ] }, tuesday => { jim => [ 3, 8 ], mary => [ 5, 5 ] }, wednesday => { jim => [ 7, 0 ], mary => [ 3 ] }, thursday => { jim => [ 4 ], mary => [ 5, 7, 2, 5, 2 ] }, friday => { jim => [ 1, 1, 5 ], mary => [ 2 ] }, };

What i found as solution is this

my $commissions = $sales->{tuesday}{jim}; my $num_sales = @$commissions; my $total = 0; foreach (@$commissions) { $total += $_; } print "Jim made $num_sales sales on Tuesday and earned \$$total commis +sion\n";

the thing that is confusing me is this part ...  my $commissions = $sales->{tuesday}{jim} and $num_sales = @$commissions From the book, to access the element of HoH you using something like my $num_sales = $sales->{friday}{mary}; but in this example, on the first line my $commissions = $sales->{tuesday}{jim}; the commissions have a reference value not the value itself. (when you try to print gave me something like ARRAY(0x94f2c3c). But if i print with @ in front like this: print "@$commissions"; it gave the value that jim have on Tuesday. From the book we have this:

my @fools = qw(jester clown motley); my $fools = \@fools; The $fools variable now contains a reference to the @fools array. You +can copy the values to another array by prepending it with the @ sign (the array sigil). my @copy_of_fools = @$fools; To access individual elements of the $fools array reference, you use t +he same syntax as you would to access the original array, but you use the dereferencing operator, +->, between the array name and the square brackets.

And this is for array. And this is one of the problem. Should $commissions have to have the value of jim already ? And how in the name of PERL :) $num_sales = @$commissions get the number of elements in the array or hash or i thing here i have another problem of dont know what this $sales is (scalar yes but what have inside :) Hashes or arrays by telling of using [] ? Sorry for the english :) !

Replies are listed 'Best First'.
Re: Hash of Hash
by davies (Monsignor) on Feb 16, 2014 at 16:29 UTC

    Looking at the book, I see that chapter 6 is on references. This is not the simplest area of Perl, but it's worth understanding because of its power. The title of your node makes me think that you may be slightly confused. In your first code snippet, $sales is a reference to an anonymous hash of hashes of arrays. It's not a simple hash of hashes (or HoH). One of the monastery's most highly rated tutorials is References quick reference, which may help you.

    To try to explain the second snippet in more detail, let's start with the first line: my $commissions = $sales->{tuesday}{jim}. This creates a reference to an array, the array being the element of the anonymous HoH containing Jim's commissions on Tuesday.

    The next line gives the number of elements in the array referenced. If you understand that $commissions is an array reference, References quick reference will explain that using the combined @$ sigils will derefer the reference, so that you are returning the array itself. However, you are returning it in "scalar context". Context is something else that often confuses people, me included (just look through my writeups). In scalar context, this returns the number of elements in an array. The latest versions of Perl have a function that makes this explicit, so you might say my $elements = scalar(@array);.

    Compare this to the use of @$commissions in the fourth line of your second snippet. Here, the array is being used in list context, meaning that each element of the array will, in turn, be put into the default variable $_. Line 5 will add them to $total, which was initialised to 0 in line 3.

    Hope this helps. I also hope that my understanding is correct. If anyone says I've got it wrong, believe them.

    Regards,

    John Davies

      However, you are returning it in "scalar context". Context is ...

      IvanAK: For a Tutorial on context, see Context tutorial, but also pay attention to the discussions in the replies thereto, and also to the links therefrom. (Update: And, in general, see the many Tutorials on this site.)

Re: Hash of Hash
by IvanAK (Acolyte) on Feb 18, 2014 at 00:59 UTC

    As i learn more about this reference thing here is what iv got. And this is all from perldoc and the pages you post here davies

    A reference is a scalar value that refers to. We all know that. The part that clear a 10% :) is: "You can't have a hash whose values are arrays; hash values can only be scalars. We're stuck with that. But a single reference can refer to an entire array, and references are scalars, so you can have a hash of references to arrays, and it'll act a lot like a hash of arrays, and it'll be just as useful as a hash of arrays."

    And also we have difference between reference and anonymous reference (or not ? but i see a little difference ). As perldoc say with this $aref=\@array; # $aref now holds a reference to @array $href = \%hash;          # $href now holds a reference to %hash we create a reference on a array and hash. $aref and $href point to them and as they are "references are scalars".

    So anonymous array or hash is (as i understand) a reference that have many reference, and those many reference can be array hash or what ever we want or what ever we point. ( write ? ) :)

    If we have simple array and we want to make reference and use it we make something like this...

    my @arr = (1,2,3,4); print "This is array: @niz\n"; my $ref = \@niz; print "This is the reference: $ref\n"; print "And this should be dereferencing or getting the value of the ar +ray through the reference : @{$ref}\n"; # This is same as (print "Thi +s is array: @niz\n";)

    or for hash

    my %h = ('Ivan'=>7, 'AK'=>8,); print "$h{'Ivan'}\n"; my $refh = \%h; print "$refh\n"; print "${$refh}{'Ivan'}\n"; print "$refh->{'Pero'}\n";

    A simple experiment :D

    So lets go back to the task from the book and the solution We have this code:

    my $sales = { monday => { jim => [ 2 ], mary => [ 1, 3, 7 ] }, tuesday => { jim => [ 3, 8 ], mary => [ 5, 5 ] }, wednesday => { jim => [ 7, 0 ], mary => [ 3 ] }, thursday => { jim => [ 4 ], mary => [ 5, 7, 2, 5, 2 ] }, friday => { jim => [ 1, 1, 5 ], mary => [ 2 ] }, }; my $commissions = $sales->{tuesday}{jim}; my $num_sales = @$commissions; my $total = 0; foreach (@$commissions) { $total += $_; } print "Jim made $num_sales sales on Tuesday and earned \$$total commis +sion\n";
    As we can see we have some anonymous hash reference named $sales. And with this first line of code my $commissions = $sales->{tuesday}{jim}; It is a reference to the hash reference of Thursday that have hash of jim ?!? ( or something ?As you say "This creates a reference to an array, the array being the element of the anonymous HoH containing Jim's commissions on Tuesday." im confusing with "=>" this ... is it a hash or array or hash that has array reference or wtf :D) inception :D :D And about $num_sales i think i got it ... if we put @ in front of reference we get the values from it and because we get the value but this value is array and we are putting it in scalar that gave us the number in array, the number of elements that the array have (something like that in my mind :D ) the other think is typical counting the element for loops etc ... that i know from other languages :D ...

    My enigma here is what kind of reference or anonymous thing is $sales.

      Hello IvanAK,

      And also we have difference between reference and anonymous reference (or not ? but i see a little difference ).

      Not really. You will find the built-in function ref useful here. Consider:

      #! perl use strict; use warnings; my %hash = ( Fred => 'Wilma', Barney => 'Betty' ); my $ref1 = \%hash; my $ref2 = { Howard => 'Marion', Richie => 'Lori Beth', Chachi => 'Joa +nie' }; printf "\$ref1 is a %s\n", ref $ref1; printf "\$ref2 is a %s\n", ref $ref2;

      Output:

      0:52 >perl 879_SoPW.pl $ref1 is a HASH $ref2 is a HASH 0:52 >

      As you can see, there is no intrinsic difference between the first reference, which is to a named hash, and the second, which is to an anonymous hash. The difference is in the way the hashes are created, not in the references to them.1

      My enigma here is what kind of reference or anonymous thing is $sales.

      $sales (a scalar variable) contains a reference to a hash. That hash happens to be an anonymous hash, because it was created that way. The values in its key-value pairs also happen to be references to hashes (and, again, those hashes were created anonymously). But that has nothing to do with what $sales is — simply, a reference to a hash.

      The “fat comma” operator => has nothing to do with creating references, it is just a convenient replacement for the comma which (1) stringifies the left-hand-side (under certain conditions) and (2) “is helpful in documenting the correspondence between keys and values in hashes, and other paired elements in lists.” — see Comma Operator.

      Hope that helps,

      1Well, OK, there is an important difference in the reference counts of the hashes: for %hash the reference count is 2, for the anonymous hash referenced by $ref2 it is 1. But that applies to the underlying data structures, not to the reference values held by $ref1 and $ref2.

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        I have to apology for making mistake on the question ... i have wrote "=>" but i was thinking about this "->".

        From perldoc i see that have 2 ways of using the reference. One way is to use "@" and the second is using ->

        " Use Rule 1 You can always use an array reference, in curly braces, in place of the name of an array. For example, "@{$aref}" instead of @array."

        "Use Rule 2 Use Rule 1 is all you really need, because it tells you how to do absolutely everything you ever need to do with references. But the most common thing to do with an array or a hash is to extract a single element, and the Use Rule 1 notation is cumbersome. So there is an abbreviation.

        "${$aref}[3]" is too hard to read, so you can write "$aref->[3]" instead.

        "${$href}{red}" is too hard to read, so you can write "$href->{red}" instead.

        If $aref holds a reference to an array, then "$aref->[3]" is the fourth element of the array. Don't confuse this with $aref[3], which is the fourth element of a totally different array, one deceptively named @aref. $aref and @aref are unrelated the same way that $item and @item are."

        "Similarly, "$href->{'red'}" is part of the hash referred to by the scalar variable $href, perhaps even one with no name. $href{'red'} is part of the deceptively named %href hash. It's easy to forget to leave out the "->", and if you do, you'll get bizarre results when your program gets array and hash elements out of totally unexpected hashes and arrays that weren't the ones you wanted to use."

        So in this case "my $commissions = $sales->{tuesday}{jim};"

        Shouldn't $commissions have the value from $sales in this case 3, 8 or something. The confusing part from this came from that line :). Here $commissions have a reference or point to reference, and as all books and doc saying that using a reference or getting the value is to pointing or use @ in front etc ...

        And you say: "The values in its key-value pairs also happen to be references to hashes" The part that also confuse me is this: "tuesday => { jim => [ 3, 8 ], mary => [ 5, 5 ] }," .... Here tuesday is a hash or reference (it must be reference because $sales can have reference in this case or im wrong? pointing to other reference anonymous (because its created using "{}" brace and have jim (again it should be reference pointing to an array in this case or reference again, reference but im confused with [] ).

        BIG apology for this noob questions :S, but i really love this language, it helps me a lot and i like to get in deep of it. Learn everything and good :)

        And of course thanks in advanced for helping me !

Re: Hash of Hash
by IvanAK (Acolyte) on Feb 20, 2014 at 01:18 UTC

    Sorry for the code part, i usually use it and trying wrote as it should.

    Athanasius thank you for explaining me and for the code that you put it. This is more clear now.

    Again thanks for all that have wrote and explain something !... going to the next chapter :D