2013-02-09 3 views
12

Я планирую передать две переменные функции perl, одна из которых может быть необязательной. Я пытаюсь проверить, определен ли второй, или нет, но он работает неправильно. Когда я вызывал функцию как myFunction (18), она предполагает, что переменная $ optional определена и переходит к инструкции else. Но в инструкции else, когда обращается к переменной $ option, она выдает «неинициализированную» ошибку. Это точно противоположно тому, что я ожидал. Любая помощь приветствуется.Использование определенного/undef в Perl

sub myFunction { 
    my ($length, $optional) = (@_); 
    if(undef($optional) 
    { 
    more code.. 
    } 
    else 
    { 
    more code... 
    } 
} 

myFunction(18) 
+4

Если вы пытаетесь выяснить, сколько передаются, затем принимают количество аргументов: 'scalar (@_)'. Если вы вызываете 'foo (4, undef)', вы передали 2 аргумента. –

+0

Это потому, что тест для неопределенного значения ['not defined'] (http://perldoc.perl.org/functions/defined.html), а не [' undef'] (http://perldoc.perl.org /functions/undef.html). – hd1

ответ

21

Правильная функция: defined. undef undefire $optional. То, что вы хотите сделать что-то вроде этого:

sub myFunction { 
    my($length, $optional) = @_; 
    if(! defined $optional) { 
     # Do whatever needs to be done if $optional isn't defined. 
    } 
    else { 
     # Do whatever can be done if $optional *is* defined. 
    } 
} 

Другой способ борьбы с ним (особенно Perl 5.10+) является использование «определено или» оператор, //, как это:

sub MyFunc { 
    my $length = shift; 
    my $optional = shift // 'Default Value'; 
    # Do your stuff here. 
} 

То, что это делает, определяет, определено ли возвращаемое значение shift @_. Поскольку вы уже вызвали сдвиг один раз, мы теперь тестируем второй параметр. Если он определен, присвойте значение $optional. Если он не определен, назначьте 'Default Value' на номер $optional. Конечно, вы должны придумать свой собственный нормальный дефолт.

Если вы застряли в темные времена предварительного Perl 5.10, вы могли бы сделать то же самое с:

my $optional = shift; 
$optional = defined $optional ? $optional : 'Default value'; 

... или ...

my $length = shift; 
my $optional = defined($_[0]) ? shift : 'Default value'; 

В любом случае, Я часто предпочитаю иметь нормальный стандарт, а не полностью отдельный путь потока управления. Это часто хороший способ упростить код.

+1

'$ SCALAR = undef;' just undefines. 'undef (VAR)' делает намного больше, даже для скаляров. (Он освобождает различные биты памяти.) – ikegami

+0

@ikegami Это правильно, но зачем усложнять вещи? Я придерживался поведения, описанного в 'perldoc -f undef'. Возможно, слово «справедливое» - это проблема. Я удалю его. – DavidO

+0

Что такое 'shift'? –

0
my $optional = defined($_[0]) ? shift : 'Default value'; 

Это опасный код, поскольку он лишь сдвигает от параметра, если определено, если у вас есть третий параметр, это будет получить запутаны, когда вы звоните

MyFunc(10, undef, 20) 
Смежные вопросы