web-dev-qa-db-ja.com

Ruby変数割り当ての二重パイプ記号?

可能性のある重複:
Rubyで はどういう意味ですか?)==

これがnewbyの質問であるかどうかは許してくださいが、Railsで本を読んでいますが、ライターがこの式をヘルパーメソッドで使用した場合:

@current_user ||= User.find_by_id(session[:user_id])

この二重パイプの使用はまだブールORステートメントですか?

もしそうなら、それはどのように機能しますか?

33
Daniel Upton

これは条件付きの割り当てです。 ここ から:

 x = find_something() #=>nil
 x ||= "default"      #=>"default" : value of x will be replaced with "default", but only if x is nil or false
 x ||= "other"        #=>"default" : value of x is not replaced if it already is other than nil or false
56

コード_foo ||= bar_は、_foo = foo || bar_とほぼ同等です。 Ruby(JavaScriptやIoなどの多くの言語と同様)では、ブール演算子は「ガード」演算子です。常にtrueまたはfalseを返す代わりに、 「真の」値に評価される最初のオペランドの値に。

たとえば、次のコードfoo = 1 || delete_all_files_from_my_computer()は何も削除しません。fooは_1_に設定され、2番目のオペランド評価されませんが設定されます。

Rubyでは、「真でない」値はnilfalseのみです。したがって、_barfooまたはfooの場合、コード_foo ||= bar_はnilのみを評価し、falseを結果に設定します。

インスタンス変数が設定されていない場合のデフォルトはnilなので、_@foo ||= bar_のようなコードは、インスタンス変数がまだ設定されていない場合に設定する一般的なRubyイディオムです。

18
Phrogz

あなたはそれを短くすると考えることができます:

@current_user = @current_user || User.find_by_id(session[:user_id])

@current_userが最初に評価され、nullでない場合、ORが短絡し、@ current_userの値が返され、User.find_by_idは呼び出されません。

(これは、Rubyがブールコンテキストでnullをfalseとして扱い、null以外をtrueとして扱うためにのみ機能します。Javaのような言語では機能しません。非ブール値を真実として扱わない)

9
Nathan Hughes