Hatena::ブログ(Diary)

bingo_nakanishiの他言語出身者のためのPerl入門

2009-08-07

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

21:13 | 第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入門



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



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

で、なんで

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

ああああ

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


それは

クォートされていないワードは文字列として扱うからなんです。

プラグマモジュール


大丈夫! 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は極めて自然に真偽値を判断してくれていると思います。