RejectTokyoRubyKaigi10でrubyとphpの比較について話してきた
スライドは、そのまま見てもあまりよく分からない(&自分が後から見ても何を意図したのか分からないと思う)ので、ここで補足しておく。
補足というか、考えていたことをぐだぐだとただ書き並べただけなのだけど。
今回の発表は Rubyにおける条件分岐の評価について、一通り自分の中で答えが出た気がしたことをまとめたものだったりします。
以前から、僕は Ruby の if 文で false と nil が 偽として評価されることがどうも気持ち悪くてなりませんでした。
FalseClass と NilClass はお互いに完全に独立しているクラスであり、それぞれの唯一のインスタンスである false と nil も当然別物である。なのに条件分岐においてのみ同一視される理由が分からなかったためです。
今では、結論というか、自分の中での折り合いとしては「それが Ruby でコードを書く上で都合が良かったから」ということになってます。
"false と nil が偽として評価される"ことは、Ruby の特性である。という認識。
基礎となる考え方の順序が異なっていたのかなぁと思っている。
こう書いてると、なんだか当たり前のことを書いているようではあるのだけど、とはいえ、基礎的な根幹の部分だからこそ、どうでも良いように見えることが大事だったりすると思うです。
さて一方、PHP における条件分岐は、boolean へキャストされた結果がそのまま評価された値となります。
ですので、 Ruby とは違い、条件分岐そのものにおいての違和感は感じません。
ちなみに、boolean へキャストされた結果 false となるのは、数値としてのゼロ(0, 0.0, 0e0)、数字のゼロ('0')、空文字('')、空配列([])、NULL です。おそらくここに引っかかりを感じる人は多いと思います。(このあたりについては、LLはPerl から入った身としては自然なのですが)
ただ、普段は 基本的に === を利用するのでほとんど気にすることがなかったのですが、下記の結果を目の当たりにしたときは目を疑いました。
<?php var_dump('0' == false); # bool(true) var_dump('0' == null); # bool(false) var_dump(null == false); # bool(true)
以来、PHP の == 演算子は、 equal ではなく、 similar なのだと思うことにしています。
これも言語で決まっていること。PHP の特性なのだと思っています。
とはいえ、== による緩やかな比較 の表(これは比較の一部でしかない)を完全に把握してコーディングしたところでバグの原因になるのは明らかなので、基本的に比較には === を使いましょう。 ってのは hnw さんもかなり以前から言っていることでもあるし、完全に同意。
とかまぁ、こんな感じでいろいろ考えていたら Ruby の演算子をオーバライドすりゃ PHP の == 実現できるんじゃね? って思って、少し前に公開してた pebbles-php_cond を利用して pebbles-php_cond-infected を書いたのが RejectTokyoRubyKaigi10 の前日。
後になって、以前見かけていた require 'php' のことを思い出して、完全に劣化版の二番煎じをしてしまったと反省。
いろんなお酒飲めて楽しかったので全て良かったのだと思うことにする。