Как установить значение по умолчанию для Perl-переменной?

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

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 (это то, что я думаю, происходит из чтения исходного кода модуля). Я предполагаю, что должен быть способ предоставить строку по умолчанию, например. В этих случаях нет ОС.

Ответ 1

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

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

Ответ 2

Обратите внимание: исходный подход ответа ($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';
    

Более подробный обзор темы (включая подробную информацию о //) находится в сообщении brian d foy здесь: http://www.effectiveperlprogramming.com/2010/10/set-default-values-with-the-defined-or-operator/

Ответ 3

Вы ищете defined?