hnwの日記

PHPの==演算子をわかりやすくするパッチ

PHPの==がキモい件」でも書きましたが、PHPの==は数値っぽいものに対してアバウトな比較を行う演算子です。

一方で、他の言語の==演算子は正確な比較を行うものばかりだと思います。他の言語の経験者がPHPソースコードを読み書きする場合に、PHPの==演算子の挙動を想像することは困難です。

つまり、PHPの==演算子の問題点は、他の言語と異なる意味にも関わらず同じ表記を採用していることにあります。見ただけで「アバウトな比較を行う」と想像できれば混乱は避けられるはずです。

そこで、PHPにパッチを当て、新たな演算子を導入してみました。

<?php

if ("01" ≒ "0x1") {
  echo '"01" ≒ "0x1" is true',"\n";
}
if ("01" ≈ "0x1") {
  echo '"01" ≈"0x1" is true',"\n";
}
if ("01" ≉ "0x1") {
  echo '"01" ≉ "0x1" is true',"\n";
} else {
  echo '"01" ≉ "0x1" is false',"\n";
}

「==」の代わりに「≒」と「≈」を、「!=」の代わりに「≉」を利用できるようにしてみました。これを実行すると下記の結果が得られます。

"01" ≒ "0x1" is true
"01" ≈ "0x1" is true
"01" ≉ "0x1" is false

パッチは下記の通りです。PHPソースコードの文字エンコーディングUTF-8を仮定しています。

--- php-5.2.9-orig/Zend/zend_language_scanner.l 2009-04-01 08:18:26.000000000 +0900
+++ php-5.2.9/Zend/zend_language_scanner.l      2009-04-01 03:17:14.000000000 +0900
@@ -1265,11 +1265,11 @@
 	return T_IS_NOT_IDENTICAL;
 }
 
-<ST_IN_SCRIPTING>"==" {
+<ST_IN_SCRIPTING>"=="|"\xe2\x89\x88"|"\xe2\x89\x92" {
 	return T_IS_EQUAL;
 }
 
-<ST_IN_SCRIPTING>"!="|"<>" {
+<ST_IN_SCRIPTING>"!="|"<>"|"\xe2\x89\x89" {
 	return T_IS_NOT_EQUAL;
 }
 

ビルドする際の注意点としては、flex 2.5.4が必要です。最新版のflexでは動作しませんので注意してください。

上記パッチを当てて、flex 2.5.4にflexという名前でパスを通してから Zend/zend_language_scanner.c を削除し、configureすればOKです。もしくは、手動で古いflexを起動する方が面倒が無いかもしれません。

なお、本パッチはジョークであり、実案件への投入などは全くお勧めしません。念のため本記事の日付もご確認ください。