Как лучше всего присвоить значение переменной, которая является ложной в Perl

Я знаю, что в Perl есть одна замечательная вещь: существует множество способов делать множество вещей, и мне было интересно, какой лучший (самый эффективный, самый надежный, быстрый) способ присвоить значение переменной, которая является ложной (0, пусто). string, undef и т. д.), некоторые из них, которые я знаю:

if ( ! $x ) {
    $x = 1;
} 
# or $x = 1 if ( ! $x );

$x = $x || 1;

$x = 1 unless $x;

$x ||= 1;

Есть ли лучший вариант?


person DarkAjax    schedule 22.03.2012    source источник
comment
Как бы вы определили, лучше ли данный способ, чем другой?   -  person jwodder    schedule 23.03.2012
comment
Может быть, быстрее или с меньшей вероятностью потерпеть неудачу?   -  person DarkAjax    schedule 23.03.2012
comment
Я не понимаю, как любой из этих способов может потерпеть неудачу, и, вероятно, в чистом Perl нет ничего быстрее....   -  person jwodder    schedule 23.03.2012


Ответы (2)


$x ||= $default;

короткая, четкая, быстрая и широко используемая (т.е. удобочитаемая).

person ikegami    schedule 22.03.2012

Вы также можете добавить операторы // и //= (проверки на определенность). Сказав это, если разница в скорости для этих методов действительно имеет значение для вашей программы, вы можете переместить части своего алгоритма за пределы perl и вместо этого вызывать его из perl (используя perl как «клей»).

Поскольку в комментариях вся педантичная полиция у меня на заднице, я нашел время, чтобы сравнить ее. Не самый лучший в мире проект по бенчмаркингу, но все же я запустил:

time perl -e 'my $a; for (1..10000000) { $a ||= $_; }; print $a;'

time perl -e 'my $a; for (1..10000000) { $a //= $_; }; print $a;'

В моей системе версия //= стабильно работает на 5-10% быстрее. YMMV.

Предполагая, что кавычки вокруг «false» в исходном вопросе означают «false», а не строго false, и, кроме того, предполагая, что undef является допустимым значением «false» в этом контексте, версия оператора undef работает примерно на 5-10% быстрее.

Если предположить, что автор вопроса ищет самый быстрый способ инициализации неинициализированной переменной, //=, вероятно, будет быстрее на основе простых тестов, которые я сделал, хотя мои комментарии по оптимизации в Perl на этом уровне остаются в силе.

person Marius Kjeldahl    schedule 22.03.2012
comment
Нет, он не может. 0 // 1 возвращает 0. - person Vladimir; 23.03.2012
comment
Как и должно быть, поскольку скаляр 0 определен. Какова твоя точка зрения? - person Marius Kjeldahl; 23.03.2012
comment
0 является ложным, и OP попросил обнаружить что-то ложное, поэтому решение должно действовать, когда начальное значение равно 0. // нет, поэтому это неправильно. Это его точка зрения. - person ikegami; 23.03.2012
comment
Он спрашивает о ложных вещах. Подсказка заключается в кавычках вокруг false в заголовке, и он специально упоминает undef в своем описании как своего рода false. Я не согласен с вашим выводом. - person Marius Kjeldahl; 23.03.2012
comment
Нет, он написал ложь и привел примеры 0, empty string, undef. Слово «ложь» — выдумка от вас, и ваш код не имеет отношения к примерам, как уже указывалось. • -1, бесполезно - person daxim; 23.03.2012