Perl: модуль CGI — передача param() в качестве параметров подпрограммам

Вопрос об использовании модуля Perl CGI:

Допустим, у меня есть подпрограмма с именем foo, которая принимает два параметра, определенных следующим образом:

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

В моей основной процедуре я беру некоторые параметры формы и передаю их в foo следующим образом:

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

Если форма не передала значение для field1 (в моем случае использовалось поле SELECT с именем field1 без значений для выбора), sub foo устанавливает $a в значение, которое было передано в $cgi->param («поле2»), которое было непустым значением.

Может ли кто-нибудь помочь мне понять, почему это происходит и почему $a не просто пустое ('') значение, а $b = значение, отправленное из $cgi->param('field2')?

Я уверен, что есть логическая причина, но я не профессионал в Perl, поэтому я уверен, что мне еще предстоит узнать или понять Perl.

Заранее спасибо!


person Vinnie    schedule 07.09.2013    source источник
comment
Вы не должны использовать здесь local (и вы не должны использовать $a и $b в качестве имен переменных, поскольку они специально используются для sort.) Вы хотите использовать my ( $foo, $bar ) = @_;   -  person friedo    schedule 07.09.2013
comment
Извините, я просто использовал $a и $b для представления любых двух переменных. Это был просто выдуманный пример, чтобы показать, чего я пытался достичь. Я никогда не использую их как настоящие параметры внутри сабвуфера. Мне любопытно, почему local считается неподходящим для объявления переменных параметров, получаемых в подпрограмме.   -  person Vinnie    schedule 07.09.2013
comment
Потому что имя local действительно неудачное. Он не создает локальные переменные. Вы создаете локализованные переменные, которые работают так, как вы ожидаете, всегда используйте my.   -  person Dave Cross    schedule 09.09.2013


Ответы (1)


Функция param() CGI ведет себя по-разному, если вызывается в списке или скалярном контексте. В скалярном контексте возвращается первое (и самое единственное) значение параметра. В контексте списка возвращаются все значения параметров (помните, что CGI позволяет иметь несколько значений для каждого ключа).

Если вы вызываете свою функцию таким образом, используется контекст списка. Это означает, что $cgi->param('field1') возвращает пустой список, а первое значение $cgi->param('field2') присваивается $a в подпрограмме. Чтобы избежать этого, вы должны явно указать скалярный контекст. Это можно сделать с помощью scalar:

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

Другая возможность заключается в использовании промежуточных переменных:

my $field1 = $cgi->param('field1'); # scalar context here
my $field2 = $cgi->param('field2');
foo($field1, $field2);
person Slaven Rezic    schedule 07.09.2013