辞書: ヨーダ記法

投稿日: 更新日:

ヨーダ記法とは

条件式の左側に、定数を配置する記法です。

  • 通常: 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に、ヨーダ記法について「過去のもの」として紹介されています。