Как использовать логические переменные в Perl?

200

Я пробовал:

$var = false;
$var = FALSE;
$var = False;

Ни одна из этих работ не работает. Я получаю сообщение об ошибке

Bareword "false" not allowed while "strict subs" is in use.
  • 36
    Вы можете начать с моей книги « Изучение Perl» . Это проще, чем угадывать, что делать, пока вы не поймете это правильно (обезьяны, пишущие машинки, и Гамлет, и все такое). :)
Теги:
boolean

8 ответов

273
Лучший ответ

В Perl следующее вычисляется как false в условных выражениях:

0
'0'
undef
''  # Empty scalar
()  # Empty list
('')

Остальные - это правда. Нет никаких простых слов для true или false.

  • 0
    Правильное сравнение, то сравнение с нулем, как в $ var = 0?
  • 0
    № 1. = это не сравнение, это назначение. 2. Сделайте "if ($ var) {...}".
Показать ещё 18 комментариев
64

Самое полное, краткое определение false, с которым я столкнулся:

Все, что указывает на пустую строку или строку `0`, является ложным. Все остальное верно.

Следовательно, следующие значения ложны:

  • Пустая строка
  • Нулевое значение
  • Значение undefined
  • Объект с перегруженным булевым оператором, который оценивает одно из указанных выше.
  • Волшебная переменная, которая оценивает одно из приведенных выше при извлечении.

Имейте в виду, что пустой литерал списка оценивает значение undefined в скалярном контексте, поэтому он вычисляет что-то ложное.


Заметка о "истинных нулях"

В то время как числа, которые строятся на 0, являются ложными, строки, нумерующие нуль, необязательно. Единственными ложными строками являются 0 и пустая строка. Любая другая строка, даже если она нумерует, равна 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")
  • 0
    если я вас правильно понял, слово true в то время как числа, которые преобразуются в 0, являются истинными, должны быть ложными или (во избежание путаницы) оцениваться как ложные .
  • 1
    Ваше «краткое» определение не соответствует вашему более длинному объяснению. Учтите: my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] }; , Теперь $value преобразуется в «XXX», но преобразуется в false.
Показать ещё 7 комментариев
58

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

my $boolean = 0;
if ( $boolean ) {
    print "$boolean evaluates to true\n";
} else {
    print "$boolean evaluates to false\n";
}

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

#!/usr/bin/perl

use strict;
use warnings;

use constant false => 0;
use constant true  => 1;

my $val1 = true;
my $val2 = false;

print $val1, " && ", $val2;
if ( $val1 && $val2 ) {
    print " evaluates to true.\n";
} else {
    print " evaluates to false.\n";
}

print $val1, " || ", $val2;
if ( $val1 || $val2 ) {
    print " evaluates to true.\n";
} else {
    print " evaluates to false.\n";
}

Строки, помеченные в "use constant", определяют константу с именем 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.

  • 7
    -1 ... см. C-faq.com/cpp/slm.html
  • 4
    use warnings; вместо #! perl -w
Показать ещё 1 комментарий
16

Я рекомендую use boolean;. Вам нужно установить модуль boolean из cpan.

  • 6
    В Perl, как и в жизни, есть много истин. Неопытным нравится писать глупости вроде if ($my_true_value == true) . Притворяться, что существует одна Истинная Истина, по моему опыту, путь к боли и неэффективный код.
  • 1
    Perl философский по своей природе
10

Мои фавориты всегда были

use constant FALSE => 1==0;
use constant TRUE => not FALSE;

которая полностью не зависит от внутреннего представления.

  • 1
    Brilliant. Вы в одиночку исправили язык программирования Perl!
7

Я наткнулся на учебник, которые хорошо объясняют Какие значения истинны и ложны в Perl. В нем указано, что:

Следующие скалярные значения считаются ложными:

  • undef - значение undefined
  • 0 число 0, даже если вы пишете его как 000 или 0.0
  • '' пустая строка.
  • '0' строка, содержащая одну цифру 0.

Все остальные скалярные значения, включая следующие, верны:

  • 1 любое не-число
  • ' ' строка с пробелом в ней
  • '00' два или более 0 символа в строке
  • "0\n" a 0, за которым следует новая строка
  • 'true'
  • 'false' да, даже строка "false" имеет значение true.

Есть еще один хороший учебник, в котором объясняется Perl true и false.

5

Красивое объяснение bobf для булевых значений: True или False? Краткое справочное руководство

Истинные тесты для разных значений

                       Result of the expression when $var is:

Expression          | 1      | '0.0'  | a string | 0     | empty str | undef
--------------------+--------+--------+----------+-------+-----------+-------
if( $var )          | true   | true   | true     | false | false     | false
if( defined $var )  | true   | true   | true     | true  | true      | false
if( $var eq '' )    | false  | false  | false    | false | true      | true
if( $var == 0 )     | false  | true   | true     | true  | true      | true
  • 0
    Плохой ответ, но сильный, авторитетный источник в perlmonks.org. Было бы неплохо иметь некоторый реальный контент вместо комментариев и ссылок. : - /
0

используйте следующий префикс файла, это добавит к вашему perl script eTRUE и eFALSE, это будет действительно REAL (!) true и false (точно так же, как java)

#!/usr/bin/perl
use 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 как значения для ключей, но этот хак будет следить за тем, чтобы правильные значения сохранялись вдоль вашего script.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню