2010-09-17 5 views
28

Является ли лучший способ проверить, инициализирована ли скалярная переменная в Perl, используя defined?Как проверить, была ли инициализирована скалярная переменная Perl?

my $var; 

if (cond) { 
    $var = "string1"; 
} 

# Is this the correct way? 
if (defined $var) { 
    ... 
} 
+0

Какая проблема вы пытаетесь решить? –

+0

Проверка 'undef' - лучший способ проверить, была ли инициализирована переменная или нет; однако это не завершит ваш тест инициализации, если переменная будет установлена ​​в 'undef' в любое время после инициализации, как указано ниже. – vol7ron

ответ

29

Perl не предлагает способ проверить, был ли или не был инициализирован переменной.

Однако скалярные переменные, которые не были явно инициализированы некоторым значением, по умолчанию имеют значение undef. Вы правы о defined, являющемся правильным способом проверить, имеет ли переменная значение undef.

Существует несколько других способов. Если вы хотите присвоить переменной, если это undef, что ваш пример кода, кажется, показывают, вы можете, например, использовать Perl, определенный или оператор:

$var //= 'a default value'; 
+12

Операторы '//' и '// =' были введены в Perl 5.10. Для предыдущих версий операторы '||' и '|| =' выполняют одно и то же, за исключением того, что они перезаписывают инициализированное «определенное, но ложное» значение, подобное «0» или «». – mob

+1

Прошу прощения, но скаляры по умолчанию являются 'undef', а оператор' defined' - это то, что Perl предлагает проверить на это значение, не вызывая предупреждения «Использовать неинициализированную переменную». («У вас все-таки есть' -w' и 'use strict', правда?) – Blrfl

+4

Blrfl: Правильно. Это ваш вопрос? Скаляр, имеющий значение undef, полностью не связан с его инициализацией или нет, поскольку perl не может отличать неинициализированные скаляры и скаляры, которые имеют значение 'undef', потому что кто-то установил его в' undef'. – rafl

5

Если вам все равно, пусто или нет, это так. В противном случае вы можете проверить.

if (length($str || '')) {} 
1

«defined» вернет true, если переменная имеет реальное значение.

Как и в сторону, в хэш, это может быть правдой:

if(exists $h{$e} && !defined $h{$e}) 
+1

'undef' - реальная ценность. Использование его в качестве индикатора для «нет значения» является, хотя и распространенным, просто конвенцией. – rafl

+0

«действительное значение» как в действительном скалярном или контрольном значении. – msbmsb

+0

В perl нет такой вещи, как недопустимый масштабирующее устройство. – rafl

3

Это зависит от того, что вы планируете делать с переменная, независимо от того, определена она или нет; по состоянию на Perl 5.10, вы можете сделать это (от perl51000delta):

Новый оператор // (определенный или) был реализован. Следующее выражение:

$a // $b 

просто эквивалентно

defined $a ? $a : $b 

и заявление

$c //= $d; 

теперь может быть использован вместо

$c = $d unless defined $c; 
9

Это зависит от того, что вы пытаетесь сделать. Правильный способ делать вещи - инициализировать переменные, когда они объявлены; Однако, Perl is not C, поэтому один из следующих может быть то, что вы хотите:

1) $var = "foo" unless defined $var;  # set default after the fact 
    2) $var = defined $var? $var : {...};  # ternary operation 
    3) {...} if !(defined $var);    # another way to write 1) 
    4) $var = $var || "foo";     # set to $var unless it's falsy, in which case set to 'foo' 
    5) $var ||= "foo";      # retain value of $var unless it's falsy, in which case set to 'foo' (same as previous line) 
    6) $var = $var // "foo";     # set to $var unless it's undefined, in which case set to 'foo' 
    7) $var //= "foo";      # 5.10+ ; retain value of $var unless it's undefined, in which case set to 'foo' (same as previous line) 


C способ делать вещи (не рекомендуется):

# initialize the variable to a default value during declaration 
# then test against that value when you want to see if it's been changed 
my $var = "foo"; 
{...} 
if ($var eq "foo"){ 
    ... # do something 
} else { 
    ... # do something else 
} 

Другой многословно способ сделать это создание класса и флага при изменении переменной, что не является необходимым.

Смежные вопросы