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

    I ran across this when trying to debug someone elses code earlier today and am just wondering what the general consensus of what this should do is.

use strict; use Data::Dumper; use CGI qw(:cgi); my $r = CGI->new(); my %hash = ( 'key1' => 'value1', 'key2' => $r->param('doesnt_exist'), 'key3' => 'value3', ); foreach my $key (keys %hash) { print "$key: $hash{$key}\n"; }
You end up with:
key1: value1 key2: key3 value3:

The param function inside of CGI.pm is returning on this statement:
return unless defined($name) && $self->{$name};
I was able to get rid of the problem by changing the call to param to:
$r->param('doesnt_exist') || undef
This keeps the has from being completely hosed.

My question is, what is wrong here... Is CGI.pm wrong, is the code wrong, is PERL wrong?

Replies are listed 'Best First'.
Re: What should this do?
by chipmunk (Parson) on Dec 05, 2001 at 09:21 UTC
    It's the code. If there are no values for a given parameter, then CGI->param() will return an empty list in list context. This is more or less necessary, because CGI has no way of knowing which parameters are expected to have a single value and which a list of values.

    Unfortunately, this is a frequent gotcha in exactly the situation you show. (It's gotten me at least once!) The hash would also be messed up if the parameter returned more than one value. The solution is to call param() in scalar context, e.g.:

    my %hash = ( 'key1' => 'value1', 'key2' => scalar $r->param('doesnt_exist'), 'key3' => 'value3', );
    or to create an anonymous array, if appropriate:
    my %hash = ( 'key1' => 'value1', 'key2' => [ $r->param('multi_valued') ], 'key3' => 'value3', );

      This is one of the reasons that I wish => imposed scalar context upon both its left and right sides. Unfortunately, rampant overuse of => as a "cute" comma in a wide variety of situations that are inconsistant with its genesis of denoting a hash's "key => value" relationship have made such an improvement pretty much impossible in Perl 5.

      I can't recall enough about Perl 6 at the moment to guess at whether this has been considered for Perl 6, would "fit in" for Perl 6, or would just no longer be an issue there. (:

              - tye (but my friends call me "Tye")
        In Perl 6, => is a constructor for the built-in PAIR datatype (see: Apocalypse 3 and Exegesis 3).

        Both arguments of the pair constructor are evaluated in scalar contexts. In the problem code above, that would cause the param method to be called in scalar context, which would cause its "empty return" to return undef instead of that pesky empty list.

        So I guess the short answer is that it...

        would just no longer be an issue there.