アラフォーからのプログラミングとデザイン

大人から始めたプログラミングとデザインについてのあれこれ

|| = という代入演算子について

railstutorial.jp

|| = という代入演算子

or equal と言う代入演算子について。出てきて気になったのでメモに記しておきます。

以外とこれについて書いてるブログとかが少なくて。

以下引用します。

この「||=」(or equals) という代入演算子はRubyで広く使われているイディオムであり、Ruby開発者を志すならこの演算子に習熟することが重要です。or equalsという概念は一見不思議にみえますが、他のものになぞらえて考えれば難しくありません。

多くのコンピュータプログラムでは、次のような記法で変数の値を1つ増やすことができます。 x = x + 1 そして、Ruby (およびC、C++、Perl、Python、Javaなどの多くのプログラミング言語) では、上の演算を次のような短縮形で表記することもできます。 x += 1 他の演算子についても同様の短縮形が利用できます

$ rails console >> x = 1 => 1 >> x += 1 => 2 >> x *= 3 => 6 >> x -= 8 => -2 >> x /= 2 => -1 いずれの場合も、●という演算子があるときの「x = x ● y」と「x ●= y」の動作は同じです。

Rubyでは、「変数の値がnilなら変数に代入するが、nilでなければ代入しない (変数の値を変えない)」という操作が非常によく使われます。4.2.3で説明したor演算子 || を使えば、次のように書くことができます。

>> @foo => nil >> @foo = @foo || "bar" => "bar" >> @foo = @foo || "baz" => "bar" nilの論理値はfalseになるので、@fooへの最初の代入「nil || "bar"」の評価値は"bar"になります。

同様に、2つ目の代入「@foo || "baz"」("bar" || "baz"など) の評価値は"bar"になります。

Rubyでは、nilとfalseを除いて、あらゆるオブジェクトの論理値がtrueになるように設計されています。

さらにRubyでは、||演算子をいくつも連続して式の中で使う場合、項を左から順に評価し、最初にtrueになった時点で処理を終えるように設計されています。

なお、このように||式を左から右に評価し、演算子の左の値が最初にtrueになった時点で処理を終了するという評価法を短絡評価 (short-circuit evaluation) と呼びます。論理積の&&演算子も似たような設計になっていますが、項を左から評価して、最初にfalseになった時点で処理を終了する点が異なります。

上記の演算子をコンソールセッション上で実際に実行して比較してみると、@foo = @foo || "bar"はx = x O yに該当し、Oが||に置き換わっただけであることがわかります。

x = x + 1 -> x += 1 x = x * 3 -> x *= 3 x = x - 8 -> x -= 8 x = x / 2 -> x /= 2 @foo = @foo || "bar" -> @foo ||= "bar" これで「@foo = @foo || "bar"」は「@foo ||= "bar"」と等価であることが理解できます。この記法をcurrent_userの文脈で使うと次のような簡潔なコードになります。 @current_user ||= User.find_by(id: session[:user_id]) お試しあれ。 補足: 技術的には、「@foo || @foo = "bar"」と書いた場合、Rubyの内部では実際にすべての項が評価されます (||が左辺にある点に注意)。これは@fooがnilやfalseでない場合に、無駄な代入を避ける必要があるためです。しかしこの式の動作では||=記法の動作と同じにならず、説明上不都合なので、上の解説では@foo = @foo || "bar" という式を用いて説明しました。  

参考 

karolgalanciak.com

www.tom08.net

以上参考にさせていただきました。

英語の文章がサラサラ読めたらもっと情報が得られるのですが。。

simpledancer.hatenablog.com