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

Hello Hash Honchos,

I have a subroutine which returns a hash, except when things go wrong, in which case it returns undef. I then want to test the result to see what happened:

my %hash = getHash(); if (%hash == undef) { print "undef\n"; } else { print "not undef\n"; }

Those of you in the know will see that this does not do what I expect. Can anyone enlighten me as to what is going on?

Thanks

loris

Replies are listed 'Best First'.
Re: How to have a subroutine return an undefined hash
by Fletch (Bishop) on Apr 26, 2005 at 12:50 UTC

    Putting aside the question of what an "undefined hash" might be, what you might do is return undef on failure and a reference to a hash if all goes well. Aside from being easier to deal with, this will be more efficient since the hash contents won't get flattened into a LIST and copied back into the destination hash.

    sub getHash { ... if( $hunky_dory ) { return \%ret_value; } else { return undef } } my $hash_ref = getHash( ); unless( defined $hash_ref ) { die "Woe is me\n"; } # ... get on with it ...

      Thanks for the help, Fletch and everyone else.

      The idea of returning a reference to the hash was the bit of wisdom I was lacking.

      loris

Re: How to have a subroutine return an undefined hash
by dragonchild (Archbishop) on Apr 26, 2005 at 12:55 UTC
    If you have a failure case, don't return undef; - just return;. That will DWIM for both scalar and list contexts. (If you don't know contexts, don't worry - it will behave correctly.)

    Then, if you want to check to see if it's got anything, just if (%hash) { ... }.


    The Perfect is the Enemy of the Good.

Re: How to have a subroutine return an undefined hash
by Roy Johnson (Monsignor) on Apr 26, 2005 at 12:38 UTC
    Using numeric equality is not how you check defined-ness. Try defined. See Fletch's note below.

    Also note that getHash should return () rather than undef to give you an undefined hash. Returning undef will give you a malformed-but-defined hash.


    Caution: Contents may have been coded under pressure.
Re: How to have a subroutine return an undefined hash
by jbrugger (Parson) on Apr 26, 2005 at 12:43 UTC
    Why do you want an undefined hash, why not create an empty one, and return the empty hash (or even better return the reference to it?)

    "We all agree on the necessity of compromise. We just can't agree on when it's necessary to compromise." - Larry Wall.
Re: How to have a subroutine return an undefined hash
by samizdat (Vicar) on Apr 26, 2005 at 12:49 UTC
    my %hash = getHash(); if (! defined(%hash)) { print "undef\n"; } else { print "not undef\n"; }

      Quoth perldoc -f defined:

      Use of "defined" on aggregates (hashes and arrays) is depre- cated. It used to report whether memory for that aggregate has ever been allocated. This behavior may disappear in future versions of Perl. You should instead use a simple test for size: if (@an_array) { print "has array elements\n" } if (%a_hash) { print "has hash members\n" }
        Gawd! Moving targets, yet. Thank you, Fletch, I stand corrected!