論理和演算子||(OR)二重のバグ [Edit]

【質問】Flash MX 2004(Flash Player 7書出し)で、以下のスクリプトの[出力]結果は、どうなるでしょう?

マニュアルを参照すると、結果を正しく予測することはできません。しかも、Flash MX 2004のコンパイラにバグがあるようです。Flashcodersで議論された問題です。

まず、Flash MX 2004オンラインヘルプの||(論理和(OR))の項に誤りがあります。戻り値は「ブール値」ではありません。この結果は、文章で表現するより、スクリプトで見た方がわかりやすいでしょう。x || yの戻り値は、以下の関数xGetOR(x, y)と同じ結果になります。

function xGetOR(x, y) {
if (Boolean(x)) { // [1]ブール(論理)値変換
return x; // [2]結果がtrueなら
} else {
return y; // [3]結果がfalseなら
}
}

まず[1]左の項(式)を、ブール(論理)値に変換します(実際にはif条件は自動的にブール値変換されます)。[2]その結果がtrueなら、左の項の値をそのまま返します。[3]結果がfalseであれば、右の項(式)の値を(それが何であっても)返します。

さて、最初の【質問】の答えは、"b"が[出力]されます。Flash Player 6までなら、これは正しい結果です。ストリングは、数値変換して0以外の数値にならないなら、ブール値としてはfalseと評価されるからです。

ところがFlash Player 7から、ストリングのブール値評価が変わりました。空文字""でないかぎり、ストリングはtrueと評価されます。実際、以下のスクリプトは、正しく"a"を[出力]します。

a = "a";
b = "b";
orResult = a || b;
trace(orResult); // 出力: a

もっとも、"a" || "b"の(正しい)結果は、Flash Playerでランタイムのスクリプト処理をするまでもなく、決まっています。つまり、定数です。Flash Player 7の仕様であれば、"a"と同値になります。したがって、プログラミングとしては、"a" || "b"と書く意味はなく、"a"と書いてしまった方が早いのです。

実は、Flash MX 2004は、コンパイル(SWF書出し)のとき、気を利かせてこの定数の最適化処理をやってくれているようです。ところが、【質問】のスクリプトでは、Flash Player 7で仕様が変わったことをうっかり忘れて、orResult = "b"と書出してしまったということです。間抜けな話というべきでしょう。

その他の記事