mursのColdFusionメモ

頭の中から抜け落ちていく情報をメモがわりに書き溜めていくブログです。

cfif で文字列を比較する時の注意

ColdFusionで文字列による値での条件分岐をする際にたびたび引っかかる問題としては、文字列として比較したつもりで決定演算子(ISとかEQ)を使っているので値として処理される点だ。

以下の条件文は、どちらも結果は「同じ」になる。

<cfset a=1>
<cfif a is "1.000">同じ<cfelse>違う</cfif>

<cfset a=0>
<cfif a is "0e1">同じ<cfelse>違う</cfif>

比較する際の値に”引用符”を付けたから文字列になるはずと思いがちだが、決定演算子や比較演算子を使った条件処理は、比較の対象となる左辺・右辺のデータを数値や日付時刻オブジェクトへの変換を試みる。これによって、上記のように一見すると違う値に見えるものでも内部では同じ数値となるため、条件は同じになる。

数値に変換された場合なら比較的発見も早いが、日付時刻オブジェクトに変換された場合は、時が経ってから(例えば、年をまたいだ後)に条件が一致⇒不一致になってしまう場合などもあり、それまで通っていた条件文が年が変わると通らなくなってしまい、混乱させる原因にもなってしまう。 (ColdFusion Administratorで「テンプレートキャッシュをクリア」するか、ページを変更するなどして再度コンパイルさせると、日付時刻オブジェクトの値も更新されて、またしばらくの間は平常に動くけど後日また動かなくなるの繰り返し)

文字列として比較する際は、compare関数を使うのが良い。 cfassociates.samuraiz.co.jp

ここまでは前置きで、最近になって、ColdFusion 2021でcfifの条件結果が違うという質問を見るようになってきた。 community.adobe.com

tracker.adobe.com

これは、比較する値がドットで終わる時に発生している(「1.」とか「2.」)。 もともとのColdFusionは、比較演算子を使用すると数値に変更するため、1.は1に変更してきた。だけども、以下のように不具合登録され、さらにColdFusion 2021では===などの演算子も追加されたことによって、ColdFusion 2021のデフォルトの動作では、1.を1に変換しなくなっている。 tracker.adobe.com

もし、以前のバージョンと同じ動きに戻したい場合は、ColdFusion 2021のjvm.configに(または AdministratorのJavaJVMJVM引数に)-Dcoldfusion.number.allowdotsuffix=true を付けることで、元のバージョンの動作に戻すことができる。