Как проверить, объявлена ​​ли переменная в perl?

perl

6207 просмотра

7 ответа

Я использую use strict;в Perl и с этим я использую следующее утверждение.

unless(defined($x)){
      print "Not defined";
}

Где $ x нигде не объявлен. Так что я ожидаю, что он напечатает " Not defined", но он возвращает ошибку

Global symbol "$x" requires explicit package name at *********** in line 15.
Автор: Shubham Источник Размещён: 12.11.2019 09:54

Ответы (7)


18 плюса

Решение

strictПрагма состоит из трех частей: строгие ссылки, строгие переменных и строгая подлодка. Тот, с кем вы сталкиваетесь,

строгие перемены

Это приводит к ошибке времени компиляции, если вы обращаетесь к переменной, которая не была объявлена ​​с помощью ourили use vars, локализована с помощью myили не была полностью квалифицирована. Поскольку это делается для того, чтобы избежать переменных проблем самоубийства и тонких проблем с динамической областью действия, просто localпеременная недостаточно хороша.

Поскольку он генерирует ошибки во время компиляции, у вашего не- BEGINкода даже не будет возможности работать. Вы можете временно разрешить не строгие переменные внутри блока, как в

{
  no strict 'vars';
  print "Not defined!\n" unless defined $x;
}

но обратите внимание, что definedоператор Perl сообщает вам, определено ли значение, а не объявлена ​​ли переменная.

Расскажите нам больше о своем заявлении, и мы сможем дать вам лучший совет о том, как с ним обращаться.

Автор: Greg Bacon Размещён: 21.08.2010 11:07

5 плюса

Вы даже не можете ссылаться на переменную, если она не объявлена. Когда вы спрашиваете

defined( $x ) ?

компилятор будет жаловаться: я не знаю, о чем вы спрашиваете, как я могу сказать, что он определен? Он не имеет ссылки на эту переменную, поскольку вы указали, что не хотите, чтобы переменные создавались автоматически по имени.

Если бы strict 'vars'он не был включен - что это по умолчанию, когда вы - use strictто это создаст запись в таблице символов пакета для «x».

Интересно, что без strict 'refs'него также легко проверить, находится ли переменная в таблице символов пакета.

defined( *{ __PACKAGE__ . '::x' }{SCALAR} )

Поскольку нет способа автоматически создать лексическое («мои переменные»), также нет стандартного способа проверить, объявлены ли лексические выражения. Лексические переменные хранятся в «блокноте». Но есть модуль, PadWalkerкоторый может помочь.

Чтобы проверить текущий уровень, вы можете получить хэш пэда, а затем проверить, существует ли он в текущем пэде. Вы также можете вернуться назад через стек (целочисленный аргумент работает примерно так caller), чтобы найти, где был самый последний x.

my $h = peek_my (0);
exists $h->{x};
Автор: Axeman Размещён: 21.08.2010 06:38

5 плюса

Я думаю, что вы смешиваете «определенные» и «объявленные» концепции.

Вы спрашиваете «Как проверить, объявлена ​​ли переменная в perl», но затем вы проверяете, определена ли переменная. Это две разные концепции.

В perl, если вы используете «использовать строгий», вы автоматически проверяете любую переменную, не объявленную (используя my , local или our ). Как только у вас есть объявленная переменная, вы можете проверить, определена ли она (назначено значение).

Таким образом, в вашем тесте вы пропускаете предварительную декларацию перед проверкой на определенность

use strict;
my $x;  # you are missing this part
[...] | # code
# your test for define
print defined $x? "defined\n" : "not defined\n";

Пожалуйста, имейте в виду, что тестирование всего за $ x неверно для вашей цели:

my ($x,$y, $z);
$w;         # not declared (use strict will catch it and die)
$x = 0;     # declared and defined BUT if you make a logic test like 'if ($x) {}' then it will be FALSE, so don't confuse testing for **'$x'** and testing for **'defined $x'**
$y = undef; # declared but not defined
$z = 1;     # declared, defined, and logial test TRUE

Наконец, ответ на ксеноррацицид кажется мне ошибочным: он предлагает «если не $ x», что не подходит для тестирования, если оно определено, как я уже говорил ранее. Он также предлагает «если не существует $ x», что неправильно для тестирования скаляров . Тест «существует» предназначен только для ключей хеширования (и не рекомендуется для массивов).

Надеюсь это поможет.

Автор: Pablo Marin-Garcia Размещён: 22.08.2010 02:02

1 плюс

 #
 print "Not defined" if !defined($x);

результат будет

Не определено

 #
 use strict;
 print "Not defined" if !defined($x);

выдаст ошибку как в вашем вопросе.

Посмотрите: http://perldoc.perl.org/strict.html , где описано, как вы можете импортировать только необходимые ограничения. (Однако использовать строгие 'vars' очень хорошая идея :))

Автор: Michael Pakhantsov Размещён: 21.08.2010 11:09

1 плюс

Обычно такого рода код не требуется для серьезной программы, но все же почему бы не просто для удовольствия: (при условии строгого использования)

print "Not defined\n" unless eval 'ref(\$x)';
Автор: Nilesh Размещён: 06.11.2012 02:29

0 плюса

#!/usr/bin/perl -l

use strict;

# if string below commented out, prints 'lol' , if the string enabled, prints 'eeeeeeeee'
#my $lol = 'eeeeeeeeeee' ;
# no errors or warnings at any case, despite of 'strict'

our $lol = eval {$lol} || 'lol' ;

print $lol;
Автор: xoid Размещён: 16.05.2013 08:08

0 плюса

мое решение #! / usr / bin / perl -l

use strict;

# if string below commented out, prints 'lol' , if the string enabled, prints 'eeeeeeeee'
#my $lol = 'eeeeeeeeeee' ;
# no errors or warnings at any case, despite of 'strict'

our $lol = eval {$lol} || 'lol' ;

print $lol;
Автор: xoid Размещён: 16.05.2013 08:26
Вопросы из категории :
32x32