Ruby で true / false を返すメソッドの実装について、いくつか書き方があると思ったのでまとめてみた。
前提
こんな感じの仕様のメソッドを実装するときのことを考える
下記条件を全て満たす場合 "true" を返し、それ以外の場合は "false" を返す、ポイント付与可能かどうかを判定するメソッド
- ログインユーザーであること
- ユーザーのステータスコードが "1" であること
<条件を整理する>
logged_in? | user.status_code | 結果 |
---|---|---|
true | 1 | true |
true | 0 | false |
false | 1 | false |
false | 0 | false |
1. 真面目実装
超真面目に実装するとこうなる。こんな書き方をしたのは久しぶりなので、なんだか気持ち悪い。こういう書き方は Ruby だとあまり見ないかも?
def pointable?
if logged_in?
if user.status_code == '1'
true
else
false
end
else
false
end
end
2. 比較演算子
比較演算子を使って実装する。
def pointable?
logged_in? && user.status_code == '1'
end
※ Ruby 触り始めは、こんな風に書いていたなー。
def pointable?
(logged_in? && user.status_code == '1') ? true : false
end
3. ガード節
- 全て満たす場合に "true" なので、ひとつでも "false" になる条件があったらその時点で return する
- 結構よく見る
- ネストが浅くなるので読みやすい
- 正常系とエラー系の処理が別れていて読みやすい
- 最後の "true" を書き忘れることがあるが(実際この前書き忘れた)、テストをちゃんと書いていれば気付けるはず
def pointable?
return false unless logged_in?
return false if user.status_code != '1'
true
end
※ if 使うか unless 使うかは好みの問題だと思うけど結構迷う。個人的には下記の2択だったら、前者の方が分かりやすくて好き。
# false を返す、もし user.status_code が '1' でないならば
return false if user.status_code != '1'
# false を返す、そうじゃないなら user.status_code が '1' である
return false unless user.status_code == '1'
4. all? メソッドを使う
こんなのも思いついたけど、どうなんでしょう。
def pointable?
[logged_in?, user.status_code == '1'].all?
end
まとめ
同じ仕様のメソッドでも、実装の仕方がいくつもあるので考えてみると楽しいです。
個人的には、2. 比較演算子
か 3. ガード節
の書き方をよく見るし読みやすくて好きなのですが、どうなんでしょう。