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

Hi Monks
I've been having a little bit of trouble with this little segment of code, and rather than rewriting it to work a different way i was wondering exactly what was wrong with it.
Here is the offending code
my %params = map ($_ => param('$_'),param()); print '-->' . $params{'listname'}. '<--' . "\n";
and here is the output from it
m1:/usr/local/nmail/cgi-bin# ./maillist.pl listname=Construction wtf -->wtf<--
I can't figure out why it is reading 'wtf' from the command line rather than the value "Construction".
I thought maybe because it is evaluating the command line as a hash rather than a list or something, i'm really not sure.
Any help would be much appreciated P.S I used strict and warnings in my code

Neil Archibald
- /dev/IT -

Replies are listed 'Best First'.
Re: CGI params
by tachyon (Chancellor) on Sep 09, 2003 at 12:46 UTC

    I suppose doing it the easy way is out of the question?

    use CGI; my $q = new CGI; my %hash = $q->Vars(); # this is faster code than map BTW my %hash; $hash{$_} = param($_) for param();

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: CGI params
by dws (Chancellor) on Sep 09, 2003 at 07:39 UTC
    I can't figure out why it is reading 'wtf' from the command line rather than the value "Construction".

    Try rewriting   my %params =  map ($_ => param('$_'),param()); as   my %params = map { $_ => param($_) } param();

      Unfortunately that didn't help, thanks for the input though, it's a really confusing error, the only thing i can think of is that it's trying to evaluate param() as a hash?

      Neil Archibald
      - /dev/IT -
        Unfortunately that didn't help, ...

        Strange. I was able to duplicate your problem (by adding   use CGI qw(:standard); to the top of that fragment). The change I offer fixes the problem, at least does when I try it. What, exactly, does your code fragment look like when you try it?

        Mine looks like this:

        C:\test>type test.pl use CGI qw(:standard); # my %params = map ($_ => param('$_'),param()); my %params = map {$_ => param($_)} param(); print '-->' . $params{'listname'}. '<--' . "\n"; C:\test>perl test.pl listname=foo bar -->foo<--
        Yet dws is right. This works for me:
        use CGI qw/:standard/; my %params = map { $_ => scalar param($_) } param(); print '-->' . $params{'listname'}. '<--' . "\n";
        Note that I added a "scalar". The error was produced by three things:
        1. You're trying to use A => B as an expression for map, which doesn't work, as "=>" is actually a comma. So map only saw the "A" as the expression, and the "B" as the first item of the list fed to it.
        2. You used single quotes around "$_" which made CGI.pm look for the parameter "'$_'", literally, which doesn't exist. Combine that with...
        3. You used param() in a list context, which for a non-existing parameter produces an empty list. "scalar" fixes that.
      So, in summary, you were filling %params with a list ( 'listname', 'wtf' ), as everything else dropped away.