Open Komodoが混乱してるげな件2007年12月01日 05時09分14秒

またもZF入門滞ってるのにこんな記事。

まぁたいした話ではないのだが、ちょっと前のエントリで取り上げたOpen Komodoがなんとなく混乱してるっぽい。

前のエントリでOpen Komodoがうまく動かなかったので、同系列(っていっていいのかな)の「Komodo Edit」をちょっとだけ試してみた。こちらはOpen Komodoと違い、なんとか起動できた。こちらの情報にもある通り、2バイトコードを含む名前のフォントが使えないのと、その影響でWin2K環境では日本語が「豆腐」になるのでちみっと困るが。

んで、本題。前回のリリースから10日ほどたつので更新されていないか見に行ってみたら、バナー下の「Downloads」のリンク先がhttp://downloads.openkomodo.com/komodoedit/nightly/latest-trunk/になってやがる。このディレクトリに設置されているファイルも「Komodo-Edit-4.3.0-alpha1-464.msi」やらになってるので、別にファイルは間違ってないけど、なんかおかしくね?

と思っていたら、

Note: Default builds out of the OpenKomodo source tree are now "Komodo Edit" -- because that is what the OpenKomodo builds basically were. Builds called "OpenKomodo" are now deprecated. Subsequent builds and releases of Komodo Edit will be from the open source OpenKomodo tree. Nightlies are available here. See this post to openkomodo-dev for details.
なんてのがあって、どうやらKomodo Editに含まれる「非オープンソース」の部分をはじき出して、Komodo Edit自体をオープンソースにするように計画を変更したらしい(自信なし。だれかこの内容を翻訳して教えてください><)。

This also allows us to reduce from three separate builds of Komodo to only two. ってことは「Open Komodo」の名前なくなるのかなぁ。最初のリリースからわずか10日でこんな自体になるとは。どんな混乱ぷりだよ。

あもきししりん?2007年12月07日 02時03分10秒

あー、最近はトラバスパム少ないし、大して面白いやつもこないので取り上げてなかったけど、久々にヘンなのがきた。英語だ。

ターゲットは「Safari3 for Winのブックマーククラッシュ解決策」で、 内容がこんなん。

Amoxicillin. Canine dosage amoxicillin. Amoxicillin side effects. Dosing of amoxicillin for sinus infection. Amoxicillin soar throat. Taking amoxicillin while pregnant.

んで、エキサイト 翻訳にかけてみると、こんなんでました。

Amoxicillin。 イヌ科の動物の投与量amoxicillin。 Amoxicillin副作用。 amoxicillinは副鼻腔感染症のために投薬されます。 Amoxicillin飛翔のど。 妊娠している間、amoxicillinを取ります。
これとSafariの関係をどう解釈しろと

「Amoxicillin」で検索かけると、どうも薬関係のものらしく、「アモキシシリン」と発音するらしい。んで、Wikipediaね。

アモキシシリン (Amoxicillin) は細菌感染症の治療に用いられる、近年開発されたβ-ラクタム系抗生物質の一つである。ペニシリン系抗生物質に属する。
だって。別に怪しいドラッグでもないし。ますますトラックバックしてきた意味がわからん

日本語でもたまにある「~といえば」系のやつなのかなぁ。

PHPにおける数値と文字列のヘンな比較結果2007年12月16日 04時09分25秒

0 == 'str' // true

PHPSPOTでこんなエントリがあった。

タイトルだけみたときは「0 == '0'のことか?そりゃ当然じゃん」とか思って記事を見たところ、
$a = 0;
$b = 'str';

if( $a == $b ) {
	echo 'equal';
} else {
	echo 'not equal';
}
なんてコードが掲載されてた。試してみると確かに「equal」と出力される。どういうこっちゃ?

仕様を調べてみる

ちょっとこの現象は、どういう理屈に基づいてこうなるのかさっぱりわからないので、仕様上どうなっているのか調べてみた。

違う型同士を比較するので、暗黙の型変換が発生するだろうと思い、マニュアルの「型の相互変換」を見てみたがそれっぽいことは記述されていなかった。

このページの最後に参照リソースとして「PHP 型の比較表」があったのでそちらを見てみると、 「==による緩やかな比較」という表には確かに数値の「0」と文字列「php」の比較結果は「TRUE」になると記載されているので、今回の現象はどうやら仕様らしいことはわかった。が、納得いかん

で、他に関連しそうなところがないかと思って目次を探してたら、「比較演算子」の項があったので見てみると、

整数値を文字列と比較する際、文字列が 数値に変換されます。
とある。ってことは、文字列'str'が暗黙的に整数に変換されたものと整数0が比較されたということのようだ。

文字列 → 数値変換ってどうなっとるの?

これで足がかりが見つかったので、もう一度「型の相互変換」から追っかけてみたところ、「文字列」の「文字列変換」の節

文字列の最初の部分により値が決まります。文字列が、 有効な数値データから始まる場合、この値が使用されます。その他の場合、 値は 0 (ゼロ) となります。
とあった。

検証してみる

なるほど、上記仕様なら、文字列'str'は数値0と見なされるので、最初のコードで「等しい」と判断されるわけだ。ではそのとおりに振舞うか、テストしてみよう。

文字列の先頭に数字を入れればその数字が示す数値に変換されるはずだし、比較する数値を0以外にしても等値にならないはずなので、最初のコードを含めて3通り試してみた。

C:\Documents and Settings\dara-j>php -r "echo 0 == 'abc' ? 'equal' : 'not equal';"
equal
C:\Documents and Settings\dara-j>php -r "echo 0 == '1abc' ? 'equal' : 'not equal';"
not equal
C:\Documents and Settings\dara-j>php -r "echo 1 == 'abc' ? 'equal' : 'not equal';"
not equal
C:\Documents and Settings\dara-j>
おお、予想通り。やっと納得がいった。

結論

比較だけなのに勝手に文字列→数値変換が発生するので気をつけようってことね。しかしこれ、仕様としてはあまり行儀が良くない気がするなぁ...

これって文字列なのか?2007年12月17日 02時16分44秒

PHPってワケワカラン深いなぁ

前回のエントリにいただいたトラックバックの記事で、またもPHPの非常識興味深い挙動に出くわした。

こちらの記事では、JavaグラマにPHPのコード組ませたら、
for ($i=0; i < count($value); $i++) {
という記述で無限ループしたとの記述。???

どんな仕様だよ

上記コードでループ条件の比較に「i」(!=$i、要するに変数じゃない)を用いたため、これが暗黙で数値「0」と見なされ無限ループになったとのことだが、これパースエラーにならんの??

ためしにこんなコードを試してみる。

C:\Documents and Settings\dara-j>php -r "echo ijk;"
ijk
C:\Documents and Settings\dara-j>
ちっともパースエラーになぞならず、しっかりと「ijk」という文字列として扱われている。わけわからん

一応マニュアルの文字列の項をざっと見てみたけど、引用符か二重引用符でくくるかヒアドキュメントにするかってくらいしか書いてなくて、どこをどう押したらこんな記述が許容されるのかさっぱりわからん。 これバグ誘発しやすいと思うけどなぁ。

ボヤキ

前回のエントリで触れた、PHPの文字列→数値の自動変換って、JavaScriptのparseInt()とほぼ同じ働きみたいだね。あんまparseInt()使ったことないけど。

$なし変数のカラクリと数値変換のお話2007年12月18日 03時44分58秒

しつこくPHPのクサレ独特の仕様についてのエントリ。だって予想外の動作ばっかりなんですもの。

できそこない変数が文字列として解釈されるワケ

昨日のエントリの「$を付け忘れた変数が文字列として解釈される」についてだが、k_37to氏のはてブコメントに解説があった。

この場合「ijk」は定数としてパースされ、定数が存在しない場合は定数名の文字列として変換される。PHPのはまりやすい罠。
定数か! 普段は慣習的に定数を大文字で記述してるので見落としていたが、なるほど定数名は定義上先頭に「$」が付かないこと以外は変数と同じだ。

そんで、マニュアルの「定数」の項を確認すると確かに

未定義の定数を使用した場合、ちょうどstringとして コールしたかのように(CONSTANT vs "CONSTANT")、 PHPはその定数自体の名前を使用したと仮定します。
PHP: 定数 - Manual(強調:dara-j)
と書いてある。これで納得。つか、未定義の定数の仕様を許容するなよ

大きな数値の怖いお話

これも暗黙の型変換に関連するのだが、今度は数値。PHPSPOTさんの記事で紹介されていた記事より。

ここで上げられていた例は、2つの17桁の数値「11111111111111111」と「11111111111111112」が等値と判断されるという、なんとも理解しがたい現象。

詳しくはリンク先を見ていただくとして、要約すると

17桁の整数 → INTの範囲外なので自動的にFLOATに → FLOATの桁精度が足りなく丸め誤差発生 → 同じ値ってことで。
ということらしい。

いや、数値なので精度による丸め誤差が発生するのはわかるんだけど、これに例の必殺技「==で比較すると整数に見なしちゃうぞ」が絡むと、

C:\Documents and Settings\dara-j>php -r "echo '11111111111111111' == 
'11111111111111112' ? 'equal' : 'not equal';"
equal
C:\Documents and Settings\dara-j>
なんて、常識的なアタマではとても思いつかない奇ッ怪な結果が提示されたりする。回避するには文字列にキャストしてstrcmp()を使用するなんて、なんともナンセンス個性的だ。

結論

PHPは余計なお世話至れり尽せりの自動変換を施してくれるので、なるべく型を意識し、値の比較時は「===」による厳密な比較を行うか、文字列経由でstrcmp()を使うなどの工夫が必要、ってとこか。って、変数に型がないのに型を強く意識したプログラミングっておかしくないか?