Perlでブール変数を使用するにはどうすればよいですか?


220

私が試してみました:

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

これらはどれも機能しません。エラーメッセージが表示される

「厳密なサブ」が使用されている間は、裸語「false」は許可されません。

37
私の本のLearning Perlから始めたいと思うかもしれません。正しくなるまで何をすべきかを推測するよりも簡単です(サル、タイプライター、ハムレットなど)。:)
ブライアン・ド・フォイ2009年

回答:


285

Perlでは、次の条件式でfalseと評価されます。

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

残りは本当です。trueまたはの裸語はありませんfalse


2
@BlueWaldo:比較結果を比較してスカラーに割り当てるときに、cmpおよび<=>を使用することもできます。$ var = $ var1 cmp $ var2; 'cmp'および '<=>'(数値比較に使用)は、左の引数が右の引数より小さい、等しい、または大きい場合、-1、0、または1を返します。ブール値ではありませんが、1つの引数が、単に等しいか等しくないのではなく、他の引数が等しいか、小さいか、大きいかを知りたい場合があります。
user118435 2009年

9
問題1:リストがtrueかfalseかを確認することができないため、空のリストはfalseではありません。スカラーコンテキストの空のリストはを返しますundef
池上2011

4
問題2:('')''は同じ値です。空の文字列で構成される要素を持つリストを暗示する必要があると思いますが(括弧でリストを作成しない場合でも)、既に述べたように、リストがtrueであるかfalseであるかを確認することは不可能です。
池上

6
問題3:オーバーロードされたブール演算子を持つオブジェクトもfalseになる可能性があります。
池上

15
@ eternicode、Perlはtrueとfalseを返す必要があるときに使用する2つの特定の値を持っているので、ブール値があるだけでなく、true(!0別名PL_sv_yes)とfalse(!1別名PL_sv_no)があります。それとも、これら2つの値以外の何かが真実かどうかテストされるときはいつでも、Perlは鳴き声を鳴らすべきだと言っていますか?それは完全にひどいでしょう。例:阻止する$x ||= $default;
池上2012

71

私が遭遇した最も完全で簡潔なfalseの定義は次のとおりです。

空の文字列または文字列に文字列化するもの0はすべてfalseです。他のすべては本当です。

したがって、次の値はfalseです。

  • 空の文字列
  • 数値ゼロ
  • 未定義の値
  • 上記のいずれかを評価するオーバーロードされたブール演算子を持つオブジェクト。
  • フェッチ時に上記のいずれかに評価される魔法の変数。

空のリストリテラルはスカラーコンテキストで未定義の値に評価されるため、何かがfalseに評価されることに注意してください。


「真のゼロ」に関するメモ

文字0列化する数値は偽ですが、ゼロに数値化する文字列は必ずしもそうではありません。唯一の偽の文字列は0空の文字列です。他の文字列は、たとえそれがゼロに数値化されたとしても、真です。

以下は、ブール値として真、数値としてゼロの文字列です。

  • 警告なし:
    • "0.0"
    • "0E0"
    • "00"
    • "+0"
    • "-0"
    • " 0"
    • "0\n"
    • ".0"
    • "0."
    • "0 but true"
    • "\t00"
    • "\n0e1"
    • "+0.e-9"
  • 警告付き:
    • Scalar::Util::looks_like_numberfalse を返す文字列。(例"abc"

0に文字列化する数値はtrueである」の「true」という単語を正しく理解している場合は、falseにするか、(混乱を避けるために)falseに評価する必要があります
user907860 2013

1
あなたの「簡潔な」定義はあなたの長い説明と矛盾しています。検討してくださいmy $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };。今度$valueは「XXX」に文字列化されますが、偽にブール化されます。
tobyink 2014

1
@tobyink、簡潔なバージョンは完璧ではなく、私が見つけた最高のものです。それはすべてを網羅するのではなく、実用的であることを意味します。によって返される値boolはに文字列化されることに注意してください0。また、一貫性のないオーバーロードを作成しないことをお勧めします。返される値はそのようなものと見なすことができます。(たとえば、&&をに最適化できる||ため、これらが一貫していない場合、問題が発生します。)
ikegami

0x00ここでカバーされているかどうかはわかりません。
Zaid

@Zaid、コード0x00(数値ゼロ)または文字列0x00looks_like_numberfalse)によって返される値を意味しますか?いずれにせよ、それはすでにカバーされています。
池上2015年

59

Perlにはネイティブのブール型はありませんが、整数または文字列の比較を使用して同じ動作を得ることができます。アランの例は、整数の比較を使用してそれを行う良い方法です。ここに例があります

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

一部のプログラムで行ったことの1つは、定数を使用して同じ動作を追加することです。

#!/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」でマークされた行は、常に1と評価されるtrueという名前の定数と、常に0で評価されるfalseという名前の定数を定義します。Perlでの定数の定義方法により、次のコード行も失敗します。

true = 0;
true = false;

エラーメッセージには、「スカラー割り当てで定数を変更できません」のようなメッセージが表示されます。

文字列の比較について尋ねたコメントの1つでそれを見ました。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で非常に一般的な混乱の原因です。


5
use warnings;代わりに#! perl -w
Brad Gilbert

11
定数を貧しい人々のマクロとして使用するのは危険です。これらのコード例は同等ではありません:if ($exitstatus) { exit; }vs if ($exitstatus == true) { exit; }は、何気ない観察者には明らかでない場合があります。(そして、はい、最後の例は貧弱なプログラミングスタイルですが、それは要点を外しています)。
Zano、

16

お勧めuse boolean;です。ただし、cpanからbooleanモジュールをインストールする必要があります。


7
Perlには、人生のように、多くの真実があります。経験の浅い人は、のようなばかげたことを書きたいif ($my_true_value == true)。私の経験では、One True Truthがあると偽ることは、苦痛への道であり、非効率的なコードです。
tjd 2014

2
Perlは本質的に哲学的です
ILMostro_7

13

私のお気に入りはいつもされています

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

これは内部表現から完全に独立しています。


5
鮮やかさ。Perlプログラミング言語を独力で修正しました!
Nostalg.io 2017

8

Perlでtrueとfalseがどのような値であるかについてよく説明されているチュートリアルに出くわしました。それは述べています:

次のスカラー値はfalseと見なされます。

  • undef -未定義の値
  • 0 000または0.0と記述した場合でも、数値0
  • '' 空の文字列。
  • '0' 1つの0桁を含む文字列。

以下を含む他のすべてのスカラー値はtrueです。

  • 1 0以外の数値
  • ' ' スペースを含む文字列
  • '00' 文字列内の2つ以上の0文字
  • "0\n" 0とそれに続く改行
  • 'true'
  • 'false' はい、文字列 'false'でもtrueと評価されます。

Perlのtrueとfalseについて説明する別の優れたチュートリアルがあります


6

ブール値に対して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

貧弱な答えで​​すが、perlmonks.orgの強力で信頼できるソースです。コメントやリンクの代わりに実際のコンテンツを用意しておくとよいでしょう。:-/
ILMostro_7

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を取得していることですが、このハックにより、スクリプトに沿って正しい値が保持されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.