bret.foreman has asked for the wisdom of the Perl Monks concerning the following question:

Perhaps I'm making a fundamental error, but I can't see why exists returns 0 instead of 1 in this code:
#!/usr/bin/perl use strict; my %testhash = { 'key1' => 'val1' , 'key2' => 'val2' }; printf "Exists for key1 = %d\n", exists $testhash{'key1'};
Thanks, Bret

Replies are listed 'Best First'.
Re: exists puzzle
by japhy (Canon) on Aug 04, 2004 at 18:49 UTC
    You are making TWO fundamental errors. You're not using warnings, which means you're not noticing the second error here. You're using curly braces when defining your hash, instead of parentheses.
    my %hash = ( ... );
    _____________________________________________________
    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: exists puzzle
by Ovid (Cardinal) on Aug 04, 2004 at 18:51 UTC

    If you enable warnings, you get the following error:

    Reference found where even-sized list expected at test.pl line 6.

    You want parentheses, not curly braces, around your key/value pairs.

    Cheers,
    Ovid

    New address of my CGI Course.

Re: exists puzzle
by ccn (Vicar) on Aug 04, 2004 at 18:53 UTC

    You by mistake used curly brackets instead of parens, so your %testhash does not have 'key1' or 'key2' keys at all. It is ({some hash ref} => undef).

    update:

    use strict; use Data::Dumper; my %testhash = { 'key1' => 'val1' , 'key2' => 'val2' }; print Dumper(\%testhash); ### $VAR1 = { 'HASH(0x2251b0)' => undef };
Re: exists puzzle
by QM (Parson) on Aug 04, 2004 at 20:22 UTC
    I would add that a quick check is to pop into the debugger. [our is used because the debugger has issues with my variables.]
    c:\perl\perl>perl -de 0 Loading DB routines from perl5db.pl version 1.19 Editor support available. Enter h or `h h' for help, or `perldoc perldebug' for more help. main::(-e:1): 0 DB<1> use strict DB<2> use warnings DB<3> our %hash = { 'key1' => 'val1', 'key2' => 'val2' }; DB<4> x \%hash 0 HASH(0x1cbd91c) 'HASH(0x1ca1f4c)' => undef
    [Code entered this way in the debugger won't give the warning the others mentioned.]

    Note here that %hash has a stringified hash as the key in it (and that key has no value). Since {...} returns a hashref here, and %hash = ... is expecting key/value pairs (or something else that looks like a hash), it grabs the hashref as the first key, stringifies it, and takes undef as the corresponding value.

    Compare that to this:

    DB<5> %hash = ( 'key1' => 'val1', 'key2' => 'val2' ); DB<6> x \%hash 0 HASH(0x1cbd91c) 'key1' => 'val1' 'key2' => 'val2' DB<7>
    which is probably what you wanted.

    For grins, try this:

    print {"key"=>"value"}, "\n";
    That's what a hashref looks like, stringified. Not terribly useful, but a recent Quiz of the Week might be an interesting detour.

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of