2010-10-18 1 views
13

Я совершенно не знаком с Perl. Мне нужно было использовать внешний модуль HTTP :: BrowserDetect. Я тестировал некоторый код и пытался получить имя ОС по методу os_string. Итак, я просто инициализировал объект и создал переменную для хранения возвращаемого значения.Как установить значение по умолчанию для Perl-переменной?

my $ua = HTTP::BrowserDetect->new($user_agent); 
my $os_name = $ua->os_string(); 

print "$user_agent $os_name\n"; 

есть некоторые пользовательские агенты, которые не являются браузерными агентами пользователей, поэтому они не получат никакого значения от os_string. Я получаю сообщение об ошибке Use of uninitialized value $os_name in concatenation (.) or string

Как обрабатывать такие случаи, когда $ os_name не инициализируется, потому что метод os_string возвращает undef (это то, что, как мне кажется, происходит от чтения исходного кода модуля). Я предполагаю, что должен быть способ предоставить строку по умолчанию, например. В этих случаях нет ОС.

ответ

17
my $os_name = $ua->os_string() || 'No OS'; 

Если $ua->os_string() является falsy (то есть: undef, ноль, или пустая строка), то вторая часть выражения || будет оцениваться (и будет значение выражения).

+0

спасибо, это действительно была очень простая проблема :). – sfactor

26

Обратите внимание: исходный подход ответа ($var = EXPRESSION || $default_value) приведет к появлению значения по умолчанию для ЛЮБЫХ «Perl false values», возвращаемых из выражения, например. если выражение представляет собой пустую строку, вместо этого вы будете использовать значение по умолчанию.

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

Если вы только хотите, чтобы избежать undef значения, но не пустая строка или нули, вы можете сделать:

  • Perl 5.10 и позже: использовать «определенный или оператор» (//):

    my $os_name = $ua->os_string() // 'No OS'; 
    
  • Perl 5.8 и выше: использовать условный оператор, так как определенный или еще не было:

    my $os_string = $ua->os_string(); # Cache the value to optimize a bit 
    my $os_name = (defined $os_string) ? $os_string : 'No OS'; 
    # ... or, un-optimized version (sometimes more readable but rarely) 
    my $os_name = (defined $ua->os_string()) ? $ua->os_string() : 'No OS'; 
    

Намного больше взгляд в глубину на эту тему (в том числе подробную информацию о //) в должности Брайан Д. Фой здесь: http://www.effectiveperlprogramming.com/2010/10/set-default-values-with-the-defined-or-operator/

+1

Недавно я ввел ошибку в свой код, используя подход '||'. Нашел вопрос до этого поста, но не знал о «определенном-или» операторе. Изучайте что-то новое с Perl каждый день. – ThisSuitIsBlackNot