🎲

【備忘録】Railsで使う書き方②~論理演算子||~

2022/06/04に公開

この記事の2回目になります。

https://zenn.dev/adverdest/articles/c8bf3fa1ed1b7f

今回扱うのは論理演算子||になります。

||を使った式の戻り値

式全体の真偽値が確定した時点で評価が終了する評価法のことを短絡評価と言います。

sample.rb
nil || false # => false
false || nil # => nil

これを使えば次のように1行で値を代入できます。

sample.rb
user = find_user("Alice") || find_user("Bob") || find_user("Carol")

自己代入

次のコードの意味は変数limitがnilまたはfalseであれば、10を代入するの意味になります。

sample.rb
limit ||= 10

limit ||= 10は次のように評価されます。

sample.rb
limit || limit = 10

limitが真であれば、limitを評価するだけで終わります。一方limitが偽であれば、limit = 10が実行されるため、limitのデフォルト値が10になります。

X ||= Aというコードを見たら「変数Xがnilまたはfalseなら,AをXに代入」と頭の中で読み変えるといいです。

デフォルト値

自己代入のところでデフォルト値という表現をしました。
これは短絡評価でも使用できます。
次の記事はJavascriptになりますが、同じ考え方になります。

https://qiita.com/Yametaro/items/17f9b2baa67440b8664a

sample.rb
 user_name = current_user.name || "ゲスト"

ログインしているユーザーが存在していればユーザーの名前を表示し、そうでなければデフォルトとして
"ゲスト"を表示します。

presence

railsにはpresenceというメソッドがあります。

https://apidock.com/rails/Object/presence

このメソッドはpresent?trueの場合にレシーバ自身を返すメソッドです。
RailsのAPIドキュメントの例を見てみましょう。

sample.rb
 region = params[:state].presence || params[:country].presence || 'US'

params[:state]とparams[:country].presenceがともにnilであればデフォルト値として
USがregionに代入されます。

presenceを使用しない場合、例えばparams[:state]が[]でくると、
これはfalseでもnilでもないため、[]が代入されてしまいます。
しかしながら、presenceを使用することでこれを回避できます。

自分が使用した例は次のようなものです。

sample.rb
 books = Books.where(available_flag = true)
 available_books = books.presence || 'ありません'

books単体だと本が該当しない場合に[]となりますが、presenceをつけることでこれを回避し、
代わりのメッセージを表示することができます。

メモ化

一度計算した値を2回目以降に呼び出した時に、再度同じ計算をしなくて済むように保存しておくことをメモ化と呼びます。

sample.rb
  def twitter_data
   @twitter_data ||= begin
     (処理)
   end
 end

このように記述するとtwitter_dataメソッドを初めて呼び出した時だけ処理が実行されます。
2回目以降の呼び出しでは@twitter_dataに保存された値が返却されるだけなので、
プログラムのパフォーマンシが向上します。

1点注意事項があります、@twitter_dataにnilが入るような場合、
2回目以降も処理が実行される点です。
これを避けるには次のように書く必要があります。

sample.rb
  def twitter_data
    return @twitter_data if instance_variable_defined?(:@twitter_data)
   @twitter_data ||= begin
     (処理)
   end
 end

https://moneyforward.com/engineers_blog/2019/03/15/ruby-code-4/

https://docs.ruby-lang.org/ja/latest/method/Object/i/instance_variable_defined=3f.html

参考文献

プロを目指す人のためのRuby入門[改訂2版] 言語仕様からテスト駆動開発・デバッグ技法まで

Discussion