ヨーダ記法とは
条件式の左側に、定数を配置する記法です。
- 通常:
if (value == 42)
- ヨーダ記法:
if (42 == value)
基本的に使ってはいけない
過去に使われていましたが、 現在は基本的には使ってはいけません。
- ヨーダ記法は基本的に読みにくい
- ヨーダ記法を使うメリットは失われている
ヨーダ記法を使うメリットは失われている
ヨーダ記法は過去に、C言語で以下のように書いたときに、 誤動作するのを避けるために使われていました。
if (value = 42) {
// valueがなんだろうと実行される
...
}
しかし、現在ではこのメリットはありません。
- Javaを含む多くの言語では、if文の条件に書くのはbooleanしか許されない。
- C言語でもif文で代入すると警告が出るようになっている。
C言語の場合
例えば、以下のファイルをmain.c
という名前で保存します。
int foo(int i) {
if (i = 42) {
return -1;
} else {
return 1;
}
}
このコードgcc -c main.c
でコンパイルすると、以下のような警告が出ます(Apple LLVM version 9.0.0)。
main.c:2:9: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
if (i = 42) {
~~^~~~
main.c:2:9: note: place parentheses around the assignment to silence this warning
if (i = 42) {
^
( )
main.c:2:9: note: use '==' to turn this assignment into an equality comparison
if (i = 42) {
^
==
1 warning generated.
Javaの場合
以下の場合は警告も出ません(FindBugs / SpotBugsでは検知できます1)
if (isAdmin = true) {
// ここは常に実行される
}
if (isAdmin = false) {
// ここは常に実行されない
}
しかし、だからヨーダ記法を使うと言うのは、論点がズレています。
なぜなら、このときに直すべき習慣は、true/falseを==
で比較することです。
具体的には、以下のように書くのが正しい習慣です。
if (isAdmin) {
// isAdminがtrueのときに実行される
}
if (!isAdmin) {
// isAdminがfalseのときに実行される
}
左側が長い場合にヨーダ記法のメリットがある?→それは論点違い
例えば、以下の2つを比べて、ヨーダ記法の方が分かりやすいという主張があります2。
if (self.getPost("main-form").getInput("title").toString() != "");
if ("" != self.getPost("main-form").getInput("title").toString());
しかし、これはそもそも論点がズレています。
なぜなら、上の例ではself.getPost("main-form").getInput("title").toString()
を
切り出して別の説明用変数を導入するのが正しい習慣です。
“foo”.equals(str)も今後は避ける
Javaの慣例として広く使われいる、定数を左に書く記法ですが、これも避けるべきです。
なぜかというと、"foo".equals(str)
という書き方をしてしまうと、nullのときの対応が曖昧になるからです。
左が定数ならnullでも"“でもfalseなのは当たり前ですが、
空文字の時はnullのときにtrueとしたい場合があります。
"".equals(str)
と書いてしまうとそのあたりが曖昧になります。
Apache Commons LangのStringUtilsクラスを使うのがいいかと思います。
参考文献
p85に、ヨーダ記法について「過去のもの」として紹介されています。