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

Hi Monks!

This line is generating an error, but what I am looking for here is a explanation of this line of code to better understand the problem. This error gets created:

"Can't use an undefined value as a HASH reference..."
This is the line of code I would like an explanation about what it is doing:

$Aoh{ testa } = @{ exec_select ($sql ) } [0] ->{ home1 };


Thanks!

Replies are listed 'Best First'.
Re: Understanding this line of Code
by davorg (Chancellor) on Jul 18, 2006 at 13:15 UTC

    Let's take it a bit at a time, working out from the centre.

    exec_select ($sql ) calls a function called "exec_select" passing it $sql.

    We assume that this function returns an array reference, deference that reference and get the first element from the dereferenced array (that's @{ exec_select ($sql ) } [0]).

    We then assume that the first element in that array contains a hash reference. We look for the "home1" key in the referenced array (that's @{ exec_select ($sql ) } [0] ->{ home1 }).

    It's at this last stage that it goes wrong. We're assuming that we have a hash reference - but Perl finds undef instead. You (obviously) can't use undef as a hash reference so Perl throws an error.

    You need to look at the value that is returned by exec_select. It is an array reference as expected, but the contents of that array (or, more specifically, the contents of the first element in that array) aren't what your code expects them to be.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      Notice how many times the word 'assume' crops up in davorg's excellent explanation? This is a place where ref() can be your friend, if only while debugging this problem. Try testing the various references to see if they are, in fact, array or hash references, like this:

      my $mystery_ref = exec_select($sql); my @temp_array = (); if (ref($mystery_ref) eq 'ARRAY') { @temp_array = @{$mystery_ref}; } else { print "Hey! I didn't get the array reference I expected, rather i +t is: ", ref($mystery_ref), "\n"; }

      If exec_select() returns an array reference, then you'll end up with that array in @temp_array, otherwise, you'll get a warning, telling you what kind of a reference it is.


      No good deed goes unpunished. -- (attributed to) Oscar Wilde
Re: Understanding this line of Code
by rafl (Friar) on Jul 18, 2006 at 13:14 UTC
    $Aoh{ testa } = @{ exec_select ($sql ) } [0] ->{ home1 };

    This piece of code basically does the following

    • Execute exec_select with $sql as its argument (exec_select($sql))
    • Dereference its return value as an array ( @{ ... } )
    • Get the first element of this array ( @{ ... } [0] )
    • Dereference the array element as a hash ( ->{ ... } )
    • Get the key 'home1' from the dereferenced hash ( ->{ home1 } )
    • Assign the value stored in the hash with the key 'home1' to $Aoh{testa}
    "Can't use an undefined value as a HASH reference..."

    This error is caused by the first element in the above array being undefined. Therefor it can't be dereferenced as a hash.

    Cheers, Flo

      This error is caused by the first element in the above array being undefined. Therefor it can't be dereferenced as an array.

      I think you mean "it can't be dereferenced as a hash".

      --
      <http://dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg

        Of course. Fixed.

        Thanks, Flo

Re: Understanding this line of Code
by chargrill (Parson) on Jul 18, 2006 at 13:13 UTC

    It looks like you have a subroutine called exec_select() that returns a reference to an array of hashes. Updated: underlined text added due to pedantry ;)

    @{ exec_select( $sql ) } refers to the list returned, [0] accesses the 0'th element, ->{ home1} dereferences the hash (of the 0'th element of the list), and assigns that hash value to your %Aoh hash, specifically the testa key of that hash.

    HTH



    --chargrill
    $,=42;for(34,0,-3,9,-11,11,-17,7,-5){$*.=pack'c'=>$,+=$_}for(reverse s +plit//=>$* ){$%++?$ %%2?push@C,$_,$":push@c,$_,$":(push@C,$_,$")&&push@c,$"}$C[$# +C]=$/;($#C >$#c)?($ c=\@C)&&($ C=\@c):($ c=\@c)&&($C=\@C);$%=$|;for(@$c){print$_^ +$$C[$%++]}
      It looks like you have a subroutine called exec_select() that returns an array of hashes.

      <pedant>
      Actually, it returns a reference to an array of hashes.
      </pedant>

      --
      <http://dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg

Re: Understanding this line of Code
by GrandFather (Saint) on Jul 18, 2006 at 20:49 UTC

    $Aoh{ testa } implies that Aoh is a hash, but the name suggests it is an array of hashes. If one assumes the name reflects the actual object then something like:

    $Aoh[0]{testa} = stuff

    is more likely correct.


    DWIM is Perl's answer to Gödel