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

210

Я пытался:

<code>$var = false;
$var = FALSE;
$var = False;
</code>

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

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

Ваш Ответ

8   ответов
16

use boolean;, Вы должны установитьлогический модуль из cpan, хотя.

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

руководство которые имеют хорошее объяснение оWhat values are true and false in Perl, Это заявляет, что:

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

undef - the undefined value 0 the number 0, even if you write it as 000 or 0.0 '' the empty string. '0' the string that contains a single 0 digit.

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

1 any non-0 number ' ' the string with a space in it '00' two or more 0 characters in a string "0\n" a 0 followed by a newline 'true' 'false' yes, even the string 'false' evaluates to true.

Есть еще один хороший учебник, который объясняетPerl правда и ложь.

67

Наиболее полное и краткое определение ложного I, с которым я сталкиваюсь, таково:

Anything that stringifies to the empty string or the string `0` is false. Everything else is true.

Поэтому следующие значения являются ложными:

  • The empty string
  • Numerical value zero
  • An undefined value
  • An object with an overloaded boolean operator that evaluates one of the above.
  • A magical variable that evaluates to one of the above on fetch.

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


A note on "true zeroes"

В то время как числа, которые преобразуются в0 ложны, строки, которые нумеруются до нуля, необязательно. Единственные ложные строки0 и пустая строка. Любая другая строка, даже если она нумеруется, равна true.

Ниже приведены строки, которые имеют значение true как логическое значение, а ноль - как число.

  • Without a warning:
    • "0.0"
    • "0E0"
    • "00"
    • "+0"
    • "-0"
    • " 0"
    • "0\n"
    • ".0"
    • "0."
    • "0 but true"
    • "\t00"
    • "\n0e1"
    • "+0.e-9"
  • With a warning:
    • Any string for which Scalar::Util::looks_like_number returns false. (e.g. "abc")
если я правильно поняла словоtrue вWhile numbers that stringify to 0 are true должно бытьfalse или (для предотвращения путаницы)evaluate to false.
Ваш & quot; краткий & quot; определение не соответствует вашему более длинному объяснению. Рассматривать:my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };, Сейчас$value будет преобразован в «XXX»; но превращается в ложное.
Я не уверен, если0x00 здесь покрыто.
@Zaid, ты имеешь ввиду значение, возвращаемое кодом0x00 (числовое значение ноль) или строка0x00 (для которогоlooks_like_number ложно)? В любом случае, это уже покрыто.
@tobyink, сжатая версия не идеальна, просто лучшее, что я нашел. Это должно быть практичным, а не всеобъемлющим. Обратите внимание, что значение, возвращаемое вашимbool делает строку в0, Кроме того, вам не рекомендуется создавать непоследовательные перегрузки, и возвращаемые вами значения можно считать таковыми. (например,&& может быть оптимизирован в||поэтому, если они противоречивы, у вас есть проблема.)
0

это добавит к вашему Perl-скрипту 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 в качестве значений для ключей, но этот хак обеспечит сохранение правильных значений в вашем сценарии.

5

bobf для логических значений:Правда или ложь? Краткое справочное руководство

Тесты правды для разных значений

                       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
Плохой ответ, но сильный, авторитетный источник в perlmonks.org. Было бы неплохо иметь немного реальногоcontent вместо комментария и ссылки. : - /
10

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

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

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

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

Остальное правда. Там нет голых слов дляtrue или жеfalse.

Могу ли я голосовать за Perl за отсутствие логических значений?
@eternicode, Perl имеет два конкретных значения, которые он использует, когда ему нужно вернуть true и false, поэтому он не только имеет логическое значение, но и true (!0 акаPL_sv_yes) и ложь (!1 акаPL_sv_no). Или вы говорите, что Perl должен хрипеть всякий раз, когда что-то кроме этих двух значений проверяется на правдивость? Это было бы совершенно ужасно. например Это помешало бы$x ||= $default;
Проблема 3: Объекты с перегруженным логическим оператором также могут быть ложными.
Проблема 2:('') а также'' одинаковое значение. Я думаю, что вы хотели подразумевать список с элементом, который состоит из пустой строки (даже если парены не создают списки), но, как я уже упоминал, невозможно проверить, является ли список истинным или ложным.
Проблема 1. Пустой список не является ложным, поскольку невозможно проверить, является ли список истинным или ложным. Пустой список в скалярном контексте возвращаетundef.
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";
}

Строки, помеченные как «использовать константу» определить константу с именем 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.

-1 ... посмотри пожалуйстаc-faq.com/cpp/slm.html
Использование констант в качестве макросов для бедняков опасно. Эти примеры кода не эквивалентны:if ($exitstatus) { exit; } противif ($exitstatus == true) { exit; }, что не может быть очевидным для случайного наблюдателя. (И да, последний пример - плохой стиль программирования, но это не относится к делу).

Похожие вопросы