Rubyコードのこの行に出会いました。これで&.
はどういう意味ですか?
@object&.method
セーフナビゲーションオペレーターと呼ばれます。 Ruby 2.3.0で導入され、オブジェクトがnil
(undefined method for nil:NilClass
エラーの回避)になることを心配せずにオブジェクトのメソッドを呼び出すことができます。これはRailsの try
メソッド と同様です。
だからあなたは書くことができます
@person&.spouse&.name
の代わりに
@person.spouse.name if @person && @person.spouse
Docs から:
my_object.my_method
これにより、my_methodメッセージがmy_objectに送信されます。任意のオブジェクトがレシーバーになることができますが、メソッドの可視性に応じてメッセージを送信するとNoMethodErrorが発生する場合があります。
&を使用できます。レシーバーを指定する場合、my_methodは呼び出されず、レシーバーがnilの場合、結果はnilになります。その場合、my_methodの引数は評価されません。
注:@Santoshは明確で完全な回答を提供しましたが、背景を追加し、重要なメモを追加したいと思います非インスタンス変数での使用に関して。
「 Safe Navigation Operator (aka "Optional chaining operator"、 "Null-conditional operator"など)」と呼ばれます。マッツはそれを「孤独なオペレーター」と呼んでいるようです。 Ruby 2.3で導入 でした。 nil
でない場合にのみ、メソッドをオブジェクトに送信します。
# Call method `.profile` on `user` only if `user` is not `nil`
@user&.profile
# Equivalent to
unless @user.nil?
@user.profile
end
上記のコードはインスタンス変数を使用していることに注意してください。ローカル変数で安全なナビゲーション演算子を使用する場合は、ローカル変数が最初に定義されていることを確認する必要があります。
# `user` local variable is not defined previous
user&.profile
# This code would throw the following error:
NameError: undefined local variable or method `user' for main:Object
この問題を解決するには、ローカル変数が最初に定義されているかどうかを確認するか、nilに設定します。
# Option 1: Check the variable is defined
if defined?(user)
user&.profile
end
# Option 2: Define your local variable. Example, set it to nil
user = nil
user&.profile # Works and does not throw any errors
Railsには、基本的に同じことを行うtry
メソッドがあります。 send
メソッドを内部的に使用して、メソッドを呼び出します。 Matz推奨 遅いため、これは組み込みの言語機能である必要があります。
他の多くのプログラミング言語にも同様の機能があります:Objective C、Swift、Python、Scala、CoffeeScriptなど。ただし、一般的な構文は?.
(疑問符)です。しかし、この構文はRubyでは採用できませんでした。 ?
はメソッド名で許可されているため、?.
シンボルシーケンスは既に有効なRubyコードです。例えば:
2.even?.class # => TrueClass
Rubyコミュニティが異なる構文を考え出さなければならなかったのはそのためです。これは活発な議論であり、さまざまなオプションが考慮されました(.?
、?
、&&
など)。考慮事項のリストは次のとおりです。
u.?profile.?thumbnails
u\profile\thumbnails
u!profile!thumbnails
u ? .profile ? .thumbnails
u && .profile && .thumbnails
# And finally
u&.profile&.thumbnails
構文を選択する際に、開発者はさまざまなEdgeのケースを検討し、議論は非常に有益です。演算子のすべてのバリエーションとニュアンスを確認したい場合は、公式Ruby課題トラッカーの この機能の紹介の説明 をご覧ください。
警戒してください!安全なナビゲーション演算子は便利ですが、それを使ってロジックを変更するように簡単に仕掛けることもできます。フロー制御での使用を避けることをお勧めします。例:
str = nil
puts "Hello" if str.nil? || str.empty?
# The above line is different than the below line
puts "Hello" if str&.empty?
最初の例では、str.nil?
はtrueを返し、str.empty?
は呼び出されないため、puts
ステートメントが実行されます。ただし、2番目の例では、str&.empty?
はfalseであるnilを返し、puts
ステートメントは実行されません。
kotlinやSwiftなどのnilチェックに使用されます。たとえば、オブジェクト-> SwiftおよびKotlinを使用
model = car?.model
carクラスでモデル値を定義していない場合、このモデルはnil(Swift)またはnull(Kotlin)になります。 Rubyでは疑問符の代わりにアンパサンドを使用します
model = car&.model
car.modelをアンパサンドなしで使用し、modelがnilの場合、システムは実行を継続できません。