Question

Question about using the Perl CGI module:

Let's say I have a sub called foo that accepts two parameters defined as follows:

sub foo {
   local($a, $b) = @_;
   print "a= [$a]";
}

In my main routine, I take some form parameters and pass them to foo like this:

use CGI;
$cgi = CGI->new;
foo($cgi->param('field1'), $cgi->param('field2'));

If the form did not pass in a value for field1, (in my case, a SELECT field called field1 with no values to choose from was used), the sub foo sets $a to the value that was passed in $cgi->param('field2'), which was a non-empty value.

Can someone help me understand why this happens and why $a isn't simply a blank ('') value and $b = the value sent in from $cgi->param('field2')?

I'm sure there's a logical reason, but I'm not a Perl pro so I'm sure it's something I've yet to learn or understand about Perl.

Thanks in advance!

Was it helpful?

Solution

CGI's param() function behaves differently if called in list or scalar context. In scalar context, the first (and most the only) parameter value is returned. In list context, all parameter values are returned (remember that CGI allows to have multiple values per key).

If you call your function like this, then list context is used. This means that $cgi->param('field1') evaluates to the empty list, and the first value of $cgi->param('field2') is assigned to $a in the subroutine. To avoid this, you have to explicitly force scalar context. This can be done by using scalar:

foo(scalar($cgi->param('field1')), scalar($cgi->param('field2')));

Another possibility is to use intermediate variables:

my $field1 = $cgi->param('field1'); # scalar context here
my $field2 = $cgi->param('field2');
foo($field1, $field2);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top