Вы можете начать с моей книги « Изучение Perl» . Это проще, чем угадывать, что делать, пока вы не поймете это правильно (обезьяны, пишущие машинки, Гамлет и все такое). :)
Брайан Д Фой
Ответы:
285
В Perl следующие условия оценивают как ложные в условных выражениях:
0'0'undef''# Empty scalar()# Empty list('')
Остальное правда. Там нет голых слов для trueили false.
@BlueWaldo: вы также можете использовать cmp и <=> при сравнении и присвоении результатов сравнения скаляру. $ var = $ var1 cmp $ var2; 'cmp' и '<=>' (используется для числовых сравнений) возвращает -1, 0 или 1, если левый аргумент меньше, равен или больше правого аргумента. Это не логическое значение, но иногда вы можете захотеть узнать, равен ли один аргумент или меньше или больше другого, а не просто равен или не равен.
user118435
9
Проблема 1: пустой список не является ложным, так как невозможно проверить, является ли список истинным или ложным. Пустой список в скалярном контексте возвращается undef.
Икегами
4
Проблема 2: ('')и ''имеют одинаковое значение. Я думаю, что вы хотели подразумевать список с элементом, который состоит из пустой строки (хотя парены не создают списки), но, как я уже упоминал, невозможно проверить, является ли список истинным или ложным.
ikegami
6
Проблема 3: Объекты с перегруженным логическим оператором также могут быть ложными.
Икегами
15
@eternicode, Perl имеет два конкретных значения, которые он использует, когда ему нужно вернуть истину и ложь, поэтому он не только имеет логическое значение, он имеет истину ( !0ака PL_sv_yes) и ложь ( !1ака PL_sv_no). Или вы говорите, что Perl должен хрипеть всякий раз, когда что-то кроме этих двух значений проверяется на правдивость? Это было бы совершенно ужасно. Например, это помешает$x ||= $default;
икегами
71
Самое полное и краткое определение ложного, с которым я сталкивался:
Все, что преобразуется в пустую строку или строку, 0является ложным. Все остальное правда.
Следовательно, следующие значения являются ложными:
Пустая строка
Числовое значение ноль
Неопределенное значение
Объект с перегруженным логическим оператором, который оценивает один из вышеперечисленных.
Магическая переменная, которая оценивает один из вышеупомянутых при получении.
Имейте в виду, что литерал пустого списка оценивается как неопределенное значение в скалярном контексте, поэтому он оценивается как нечто ложное.
Записка о "истинных нулях"
В то время как числа 0, которые преобразуются в строку, являются ложными, строки с нумерацией не обязательны. Единственными ложными строками являются 0и пустые строки. Любая другая строка, даже если она нумеруется, равна true.
Ниже приведены строки, которые имеют значение true как логическое значение, а ноль - как число:
Без предупреждения:
"0.0"
"0E0"
"00"
"+0"
"-0"
" 0"
"0\n"
".0"
"0."
"0 but true"
"\t00"
"\n0e1"
"+0.e-9"
С предупреждением:
Любая строка, для которой Scalar::Util::looks_like_numberвозвращается false. (например "abc")
если я вас правильно понял, слово true в то время как числа, которые преобразуются в 0, являются истинными, должны быть ложными или (во избежание путаницы) оцениваться как ложные .
Дмитрий Королев
1
Ваше «краткое» определение не соответствует вашему более длинному объяснению. Рассмотрим: my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };. Теперь $valueпреобразуется в "XXX", но преобразуется в false.
tobyink
1
@tobyink, сжатая версия не идеальна, просто лучшее, что я нашел. Он должен быть практичным, а не всеобъемлющим. Обратите внимание, что значение, возвращаемое вашей boolстрокой действительно 0. Кроме того, вам не рекомендуется создавать непоследовательные перегрузки, и возвращаемые вами значения можно считать таковыми. (например, a &&можно оптимизировать в a ||, поэтому, если они противоречивы, у вас возникнет проблема.)
ikegami
Я не уверен, что 0x00здесь кроется.
Заид
@Zaid, Вы имеете в виду значение, возвращаемое кодом 0x00(числовое значение ноль) или строкой 0x00(для которой looks_like_numberложно)? В любом случае, это уже покрыто.
Икегами
59
Perl не имеет собственного логического типа, но вы можете использовать сравнение целых чисел или строк, чтобы получить то же поведение. Пример Алана - хороший способ сделать это, используя сравнение целых чисел. Вот пример
my $boolean =0;if( $boolean ){print"$boolean evaluates to true\n";} else {print"$boolean evaluates to false\n";}
Одна вещь, которую я сделал в некоторых из моих программ, добавила то же самое поведение, используя константу:
Строки, помеченные как «константа использования», определяют константу с именем true, которая всегда оценивается как 1, и константу с именем false, которая всегда оценивается как 0. Из-за способа определения констант в Perl следующие строки кода также дают сбой:
true =0;
true = false;
Сообщение об ошибке должно содержать что-то вроде «Не удается изменить константу в скалярном присваивании».
Я видел это в одном из ваших комментариев о сравнении строк. Вы должны знать, что поскольку Perl объединяет строки и числовые типы в скалярных переменных, у вас есть другой синтаксис для сравнения строк и чисел:
my $var1 ="5.0";my $var2 ="5";print"using operator eq\n";if( $var1 eq $var2 ){print"$var1 and $var2 are equal!\n";} else {print"$var1 and $var2 are not equal!\n";}print"using operator ==\n";if( $var1 == $var2 ){print"$var1 and $var2 are equal!\n";} else {print"$var1 and $var2 are not equal!\n";}
Разница между этими операторами является очень распространенным источником путаницы в Perl.
Использование констант в качестве макросов для бедняков опасно. Эти примеры кода не эквивалентны: if ($exitstatus) { exit; }vs if ($exitstatus == true) { exit; }, что может быть неочевидно для случайного наблюдателя. (И да, последний пример - плохой стиль программирования, но это не относится к делу).
Зано
16
Я рекомендую use boolean;. Вы должны установить логический модуль из cpan, хотя.
В Perl, как и в жизни, есть много истин. Неопытные любят писать глупые вещи вроде if ($my_true_value == true). По моему опыту, притворяться, что существует одна истинная истина, - это путь к боли и неэффективный код.
'17
2
Perl философский по своей природе
ILMostro_7
13
Мои любимые всегда были
use constant FALSE =>1==0;use constant TRUE => not FALSE;
который полностью независим от внутреннего представления.
Плохой ответ, но сильный, авторитетный источник в perlmonks.org. Было бы неплохо иметь реальный контент вместо комментариев и ссылок. : - /
ILMostro_7
0
используйте следующий префикс файла, это добавит к вашему Perl-скрипту eTRUE и eFALSE, на самом деле это будет REAL (!) true и false (как java)
#!/usr/bin/perluse strict;use warnings;use constant {#real true false, compatible with encode_json decode_json for later (we don't want field:false... will be field:0...)
eTRUE => bless(do{\(my $o =1)},'JSON::PP::Boolean'),
eFALSE => bless(do{\(my $o =0)},'JSON::PP::Boolean')};
Есть, на самом деле, несколько причин, почему вы должны использовать это.
Моя причина в том, что при работе с JSON у меня есть 0 и 1 в качестве значений ключей, но этот хак обеспечит сохранение правильных значений в вашем скрипте.
Ответы:
В Perl следующие условия оценивают как ложные в условных выражениях:
Остальное правда. Там нет голых слов для
true
илиfalse
.источник
undef
.('')
и''
имеют одинаковое значение. Я думаю, что вы хотели подразумевать список с элементом, который состоит из пустой строки (хотя парены не создают списки), но, как я уже упоминал, невозможно проверить, является ли список истинным или ложным.!0
акаPL_sv_yes
) и ложь (!1
акаPL_sv_no
). Или вы говорите, что Perl должен хрипеть всякий раз, когда что-то кроме этих двух значений проверяется на правдивость? Это было бы совершенно ужасно. Например, это помешает$x ||= $default;
Самое полное и краткое определение ложного, с которым я сталкивался:
Следовательно, следующие значения являются ложными:
Имейте в виду, что литерал пустого списка оценивается как неопределенное значение в скалярном контексте, поэтому он оценивается как нечто ложное.
Записка о "истинных нулях"
В то время как числа
0
, которые преобразуются в строку, являются ложными, строки с нумерацией не обязательны. Единственными ложными строками являются0
и пустые строки. Любая другая строка, даже если она нумеруется, равна true.Ниже приведены строки, которые имеют значение true как логическое значение, а ноль - как число:
"0.0"
"0E0"
"00"
"+0"
"-0"
" 0"
"0\n"
".0"
"0."
"0 but true"
"\t00"
"\n0e1"
"+0.e-9"
Scalar::Util::looks_like_number
возвращается false. (например"abc"
)источник
my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };
. Теперь$value
преобразуется в "XXX", но преобразуется в false.bool
строкой действительно0
. Кроме того, вам не рекомендуется создавать непоследовательные перегрузки, и возвращаемые вами значения можно считать таковыми. (например, a&&
можно оптимизировать в a||
, поэтому, если они противоречивы, у вас возникнет проблема.)0x00
здесь кроется.0x00
(числовое значение ноль) или строкой0x00
(для которойlooks_like_number
ложно)? В любом случае, это уже покрыто.Perl не имеет собственного логического типа, но вы можете использовать сравнение целых чисел или строк, чтобы получить то же поведение. Пример Алана - хороший способ сделать это, используя сравнение целых чисел. Вот пример
Одна вещь, которую я сделал в некоторых из моих программ, добавила то же самое поведение, используя константу:
Строки, помеченные как «константа использования», определяют константу с именем true, которая всегда оценивается как 1, и константу с именем false, которая всегда оценивается как 0. Из-за способа определения констант в Perl следующие строки кода также дают сбой:
Сообщение об ошибке должно содержать что-то вроде «Не удается изменить константу в скалярном присваивании».
Я видел это в одном из ваших комментариев о сравнении строк. Вы должны знать, что поскольку Perl объединяет строки и числовые типы в скалярных переменных, у вас есть другой синтаксис для сравнения строк и чисел:
Разница между этими операторами является очень распространенным источником путаницы в Perl.
источник
use warnings;
вместо#! perl -w
if ($exitstatus) { exit; }
vsif ($exitstatus == true) { exit; }
, что может быть неочевидно для случайного наблюдателя. (И да, последний пример - плохой стиль программирования, но это не относится к делу).Я рекомендую
use boolean;
. Вы должны установить логический модуль из cpan, хотя.источник
if ($my_true_value == true)
. По моему опыту, притворяться, что существует одна истинная истина, - это путь к боли и неэффективный код.Мои любимые всегда были
который полностью независим от внутреннего представления.
источник
Я наткнулся на учебник, в котором есть хорошее объяснение того, какие значения являются истинными и ложными в Perl . Это заявляет, что:
Следующие скалярные значения считаются ложными:
undef
- неопределенное значение0
число 0, даже если вы пишете его как 000 или 0.0''
пустая строка.'0'
строка, которая содержит одну цифру 0.Все остальные скалярные значения, включая следующие, верны:
1
любое число не 0' '
строка с пробелом в нем'00'
два или более 0 символов в строке"0\n"
0 с последующим переводом строки'true'
'false'
да, даже строка 'false' оценивается как true.Есть еще один хороший учебник, который объясняет Perl, правда и ложь .
источник
Прекрасное объяснение, данное bobf для логических значений: True или False? Краткое справочное руководство
Тесты правды для разных значений
источник
используйте следующий префикс файла, это добавит к вашему Perl-скрипту eTRUE и eFALSE, на самом деле это будет REAL (!) true и false (как java)
Есть, на самом деле, несколько причин, почему вы должны использовать это.
Моя причина в том, что при работе с JSON у меня есть 0 и 1 в качестве значений ключей, но этот хак обеспечит сохранение правильных значений в вашем скрипте.
источник