Как избежать ошибок с параметрами командной строки Perl и использовать строгий - PullRequest
7 голосов
/ 07 марта 2012

Почему мой код не работает после добавления use strict; use warnings;? Есть ли способ заставить его работать?

Ранее рабочий код:

#!/usr/bin/perl -s
print "x: $x\n";
print "y: $y\n";

Я выполнил команду perl -s test.pl -x="hello" -y="world". Выход:

x: hello
y: world

Однако после добавления use strict; use warnings; я получил следующие ошибки:

Variable "$x" is not imported at test.pl line 4.
Variable "$y" is not imported at test.pl line 5.
Global symbol "$x" requires explicit package name at test.pl line 4.
Global symbol "$y" requires explicit package name at test.pl line 5.
Execution of test.pl aborted due to compilation errors.

Я знаю, что нужно объявить my $x и my $y, чтобы исправить 3-ю и 4-ю ошибку. Но что означают первые 2 ошибки и как мне их преодолеть?

Ответы [ 3 ]

9 голосов
/ 07 марта 2012

На самом деле, объявление этих переменных как лексических (my) переменных не поможет, потому что слишком поздно: переключатель -s уже установит их. Он устанавливает глобальные (пакетные) переменные (в вашем случае, $main::x и $main::y или & mdash; в качестве специальных сокращений - $::x и $::y). Если вы не хотите ссылаться на них, используя их имена с указанием пакета, вы можете использовать объявление our, чтобы указать, что пустые имена $x и $y относятся к $x и $y в текущем пакете:

our ($x, $y);
print "x: $x\n"; 
print "y: $y\n";

(Наконечник шляпы Дероберту за указание, что вы можете использовать our для этого.)

Кроме того, вы можете скопировать глобальные переменные в лексические переменные с одинаковыми именами:

my ($x, $y) = ($::x, $::y);
print "x: $x\n";
print "y: $y\n";

Это позаботится об обоих наборах диагностики.

4 голосов
/ 07 марта 2012

Вы используете элементарный синтаксический анализатор переключателей perl -s, который использует глобальные переменные. Чтобы заставить его работать с use strict, вам нужно обратиться к глобальным переменным: $main::x, как указал Руах.

Но даже в этом случае лексические переменные (объявленные с my) предпочтительны практически во всех случаях. Просто сделай:

use strict;
use warnings;

my ($x, $y) = @ARGV;
print "x: $x\n";
print "y: $y\n";

И использовать с:

perl test.pl hello world

Для более подробной информации и работы с переключателями, см. Модуль Getopt :: Long .

2 голосов
/ 07 марта 2012

Чтобы понять, что означает ЛЮБАЯ ошибка / предупреждение Perl, вы можете обратиться к perldiag.

В частности, для слова «не импортировано» написано:

Переменная "% s" не импортирована.% S

(W misc). По сути, вы используете ссылку "строгий", ссылаясь на глобальную переменную, которая, по-видимому, считалась импортированной из другого модуля.потому что что-то еще с тем же именем (обычно подпрограмма) экспортируется этим модулем.Обычно это означает, что вы поместили неправильный забавный символ в начале своей переменной.

По сути, Perl сделал два разных предположения о вашем необъявленном идентификаторе $x - это был либо

  1. глобальная область пакета, использование которой запрещено по strict ("Глобальному символу" $ x "требуется явный пакет")

  2. или это была попытка использовать переменную другого пакета, которая должна была быть импортирована, но ее не было («Переменная» $ x «не импортирована»).

Perl не может сказать, какие из двух теорий верны, поэтому выплюнули обе возможности.Последняя ошибка (глобальный символ «$ x» требует явного имени пакета) была правильной в этом случае - это БЫЛА глобальная переменная в вашем исходном пре-строгом коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...