piyush.shourie has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am passing the reference of a HASH to a method, which does not produce the desired result.

Refer the following code:

use XML::Simple; my $config = XMLin("SAMLResponse with attrs.xml"); traverseHash($config); sub traverseHash { my $hRef=@_; print ref($hRef); }

The above code produces no output, indicating that the parameter received is not a hash. However, if the type of variable $config is checked using ref() method, it clearly indicates that it is a HASH.

Please clarify this discrepancy in the result.

Thanks in advance,
Piyush

Replies are listed 'Best First'.
Re: Passing Reference of a Hash to a method
by davorg (Chancellor) on Nov 23, 2004 at 10:37 UTC

    Your variable $hRef will contain the value '1'.

    You are evaluating an array (@_) in scalar context, which returns the number of elements in the array (in this case, 1).

    To get round this, either extract a useful scalar from @_ using one of these approaches:

    my $hRef = shift; my $hRef = $_[0];

    Or change the assigment to a list assignment:

    my ($hRef) = @_;
    --
    <http://www.dave.org.uk>

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

Re: Passing Reference of a Hash to a method
by dave_the_m (Monsignor) on Nov 23, 2004 at 10:36 UTC
    my $hRef=@_;
    That should be
    my ($hRef)=@_;
    An array in scalar context returns the number of elements, not the first element.

    Dave.

Re: Passing Reference of a Hash to a method
by edan (Curate) on Nov 23, 2004 at 10:35 UTC
Re: Passing Reference of a Hash to a method
by Zaxo (Archbishop) on Nov 23, 2004 at 10:40 UTC

    In,     my $hRef=@_; you're forcing @_ into scalar context, yielding count of its elements. As called, that is 1, and ref(1) gets you undef.

    Fix this by making the assignment happen in list context:

    sub traverseHash { my ($hRef) = @_; print ref($hRef); }

    After Compline,
    Zaxo

      ref never returns undef. Even ref(undef) returns an empty string.
      local $\ = "\n"; print defined ref undef; print length ref undef;
      prints
      1
      0
      
Re: Passing Reference of a Hash to a method (simpler)
by Luca Benini (Scribe) on Nov 23, 2004 at 11:31 UTC
    also:
    my $hRef=shift;
Re: Passing Reference of a Hash to a method
by rrwo (Friar) on Nov 23, 2004 at 18:25 UTC

    You were assigning a list of arguments to a scalar, which was a scalar of the number of arguments ("1"). The ref of a non-reference is blank. Try this:

    sub traverseHash { my $hRef=shift; print ref($hRef); }

      Er... no. If the original poster was assigning a list to a scalar, then the behaviour of the comma operator would ensure that he ended up with the last element in the list in the scalar variable - which would have been what he wanted.

      my $scalar = ('this', 'is', 'a', 'list'); print $scalar; # prints 'list'

      The problem was caused because he was assigning an array, not a list.

      Please read What is the difference between a list and an array? from perlfaq4 which explains this difference in more detail.

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

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