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

I am having a below code :
join(";" ,$hXCR{$M}{GD} {0}{SKT}||0 ,$hRCX1{$M}-> {GD}->{'*'}->{SKT}|| +0 );
I am not getting what $hXCR{$M}{GD} {0}{SKT}||0 this indicates. I understand $hXCR{$M}{GD} is a hash with key and value but then what {0}{SKT}||0 means here and what is this code about $hRCX1{$M}-> {GD}->{'*'}->{SKT}||0 I mean what arrow indicating here.

Replies are listed 'Best First'.
Re: query on hash understanding
by Athanasius (Archbishop) on Sep 24, 2014 at 07:44 UTC

    Hello Ritz@Perl, and welcome to the Monastery!

    First, please put your code in <code> ... </code> tags to make it easier to read.

    Now to your question. Consider the following, which shows your code in an example context:

    #! perl use strict; use warnings; my %hXCR = ( X => { GD => { 0 => { SKT => 17 } } } ); my %hRCX1 = ( X => { GD => { '*' => { SKT => '' } } } ); my $M = 'X'; my $s = join ( ";", $hXCR{$M}{GD}{0}{SKT} || 0, $hRCX1{$M}->{GD}->{'*'}->{SKT} || 0, ); print "\n\$s = |$s|\n";

    Output:

    17:41 >perl 1026_SoPW.pl $s = |17;0| 17:41 >

    Yes, $hXCR is a hash with the value of $M as one of its keys. But the value is not GD, it is a reference; specifically, a reference to an anonymous hash which has GD as one of its keys. The value corresponding to GD is another reference to another anonymous hash, this time with 0 as a key and a third reference to a third anonymous hash as its corresponding value. The third anonymous hash contains a key SKT and a corresponding value; so the whole expression:

    $hXCR{$M}{GD}{0}{SKT}

    evaluates to that value (which is 17 in my example).

    The expression || 0 means: if the value is “true” (according to Perl’s definition of truth), then the expression evaluates to the value on the left-hand side; but if it’s “false”, then the whole expression evaluates to 0. For example, in my script the second expression is the empty string, which in Perl is false, so the expression becomes 0 as you can see in the output.

    Arrows are used to de-reference variables containing references, but in this case they are not needed. To get an understanding of all this, please read perlreftut, perldsc, and perllol.

    Updates: (1) Improved wording slightly.

    (2) This is what helped me to understand Perl’s complex data structures: In Perl, there are three kinds of variables: scalar, array, and hash. The first is singular, the second and third are plural. But the elements contained by an array or hash can only be scalars. To get an array of arrays (say), you need a way of representing an array (the inner one) as a scalar. That’s where references come in: take a reference to an array, and you have a scalar which can be (i) dereferenced to access the array, but also (ii) itself stored as an element in an array (the outer one).

    (3) For Perl’s definition of “true” and “false”, see perlsyn#Truth-and-Falsehood.

    Hope that helps,

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

Re: query on hash understanding
by LanX (Saint) on Sep 24, 2014 at 07:36 UTC
    Please use code tags to be readable.

    See perldsc for a description of nested data structures like hashes of hashes.

    There you'll learn about the meaning of dereferencing operator -> which can be dropped between parens like }{ .

    See also perlref

    x||0 (ie x or 0) just means return 0 if LHS x is false.

    HTH! :)

    Cheers Rolf

    (addicted to the Perl Programming Language and ☆☆☆☆ :)

Re: query on hash understanding
by Anonymous Monk on Sep 24, 2014 at 07:31 UTC
Re: query on hash understanding
by GotToBTru (Prior) on Sep 24, 2014 at 14:36 UTC

    The $hash{key} = $value || 0 construct avoids a value of undefined. It is like setting a default value, or if you are familiar with SQl, like the NVL() function. If you are going to test the value of a variable later in the program, and the value might be undefined, this is used to avoid "Use of uninitialized value" warnings.

    use strict; use warnings; my (%hash, $value); print "Without\n"; $hash{key} = $value; if ($hash{key} == 42) { print "taking appropriate action\n" } print "With\n"; $hash{key} = $value || 0; if ($hash{key} == 42) { print "taking appropriate action\n" }

    Output:

    /wlsedi/howard$: perl pm.pl Without Use of uninitialized value in numeric eq (==) at pm.pl line 10. With /wlsedi/howard$:
    1 Peter 4:10

      This is an excellent point, but note that where the intent is to avoid an undefined value, the defined-or operator // is a better choice than the logical-or operator ||, because:

      1. It will not override a false value (such as the empty string) in an already-defined variable.
      2. It makes the intention of the code clearer.

      Hope that’s of interest,

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