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

Given the following hash:
my %hash = ('one' => 1, 'two' => {'one' => 1, 'two' => {'one' => 1, 'two' => 2, 'three' => 3}}, 'three' => 1);
I need to know if a given key equals a value or is a hash ref. The following code performs the check that I need, but only if strict is turned off:
if ((keys %{$hash{'one'}})) { print "Yes\n"; } else { print "No\n"; }
When Strict is being used it yields the following error, "Can't use string ("1") as a HASH ref while "strict refs" in use." What would be the best way to do this and leave strict enabled?

Replies are listed 'Best First'.
Re: Testing for hash key value
by djantzen (Priest) on May 26, 2003 at 02:28 UTC

    What you need is ref. For example:

    foreach my $val (values %hash) { if (ref $val eq 'HASH') { # Update: oops, was numeric equality; th +anks chromatic print "Hash\n"; } else { print "Not Hash\n"; } }

    That said, using ref for this sort of thing often means you need to do some refactoring. For further discussion, see Testing for existence of subroutine ref?.


    "The dead do not recognize context" -- Kai, Lexx
Re: Testing for hash key value
by jepri (Parson) on May 26, 2003 at 02:25 UTC
    That's because the code %{$hash{'one'}} actually says to perl "take the hash key value stored in $hash{'one'} and pretend it is a hash reference". Since it isn't a hash reference, perl throws an error. Just remove the %{} from that if statement and your code will work the way you want it to.

    Update: djantzen kindly pointed out what I overlooked - that you also have to remove the 'keys' command or perl will still throw an error. However this leads to a rather nice way to check for what you want:

    if ((eval"%{$hash{'one'}}")) { print "It's a hash\n"; } else { print "It's not a hash\n"; }

    So it turns out there's more than one way to do it :)

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.