第135回 Perlに true, falseなんてない

あ、そこの君!
だまされたと思ってこれを実行していきなさい。

if( false ){
  print "ああああ\n";
}

どんな結果になったかね?
そうだ。

ああああ

こう表示されただろう。


ことの発端

この事実に気づいたのは、あるJS使いから

if( !false ){
  print "ああああ\n";
}

が trueにならないんだけど、どういうこと?
と質問があったからだ。



とあるC言語経験者の発言

そもそもC言語にも true, falseはないよね。
と言うのは、あるC言語経験者の発言。


ブーリアン型 - Wikipedia

C言語では、C89 にはブーリアン型が定義されていない(C99には定義されている)。ブーリアン型がない代わりに true/false は 0 かどうかで判断される。


C++では、標準化の過程で bool、true、false というキーワードが導入され、基本データ型としてサポートされた。その大きさは処理系で定義される。

だそうです。


Perlにも true, falseなんてないのさ

Perlの真偽値のルールは以下のような感じです。
Perlにおける真偽値 - Perl入門ゼミ



ラクダ本にバッチリ、ルールが載っていますが、残念ながら会社に置いてきているので参照できませんでした><

プログラミングPerl〈VOLUME1〉

プログラミングPerl〈VOLUME1〉


結局、 if( false ){ } はなんで真なの?

で、なんで

if( false ){
  print "ああああ\n";
}

ああああ

このように表示されてしまうのでしょう。


それは
クォートされていないワードは文字列として扱うからなんです。
http://outsider.imawamukashi.com/Perl/pragmatic_module.html

大丈夫! use strict; が僕らを守ってくれるぞ

そ!そんな馬鹿な話が!!
とお思いの方!

今や常識, use strict;を書けば僕らを守ってくれるぞ。

use strict;
if( false ){
  print "ああああ\n";
}

結果:

Bareword "false" not allowed while "strict subs" in use at e line 4.
Execution of e aborted due to compilation errors.

じゃあ今まで 1 == 1 は trueとか教わってたけど いったい何が返ってきてるんだ?

ん〜 trueとfalseがないなら比較演算子はなにを返してきてるんだろう...
実行してみました。

use Data::Dumper;

print Dumper false;                 # use strictを付けてないので 文字列の'false'
print Dumper true;                  # use strictを付けてないので 文字列の'true'

print Dumper 'aa' eq 'aa';          # 1
print Dumper 1 == 1;                # 1

print Dumper 'aa' ne 'aa';          # ''
print Dumper 1 != 1;                # ''

print Dumper !('aa' eq 'aa');       # ''
print Dumper !('aa' ne 'aa');       # 1

真だと 1
偽だと ''
のようですね。

openは何を返しているのだろう?

use strict;
use Data::Dumper;

# 存在しないファイル
print Dumper open my $c, '<', 'aaaaaaaa.txt';     # undef

# 存在するファイル
print Dumper open my $c, '<', 'p.txt';            # 1

存在しないファイルの場合は undef
存在するファイルの場合は 1なので、
Perlが偽、真と判断できるものがちゃんと返ってきていますね。


ということで

真偽にあたる true, falseは、まああるけども、
予約語的な true, falseはないですよ。
というお話でした。


今回は、上記のようなお話でしたから、Perlのifは使い辛いと感じられたかたもいらっしゃるかもしれませんが、私はPerlは極めて自然に真偽値を判断してくれていると思います。