Jawaban:
Ini disebut Operator Navigasi Aman. Diperkenalkan di Ruby 2.3.0, ia memungkinkan Anda memanggil metode pada objek tanpa khawatir objek itu mungkin nil
(Menghindari undefined method for nil:NilClass
kesalahan), mirip dengan try
metode di Rails .
Jadi kamu bisa menulis
@person&.spouse&.name
dari pada
@person.spouse.name if @person && @person.spouse
Dari Documents :
my_object.my_method
Ini mengirimkan pesan my_method ke my_object. Objek apa pun bisa menjadi penerima tetapi tergantung pada visibilitas metode mengirim pesan dapat meningkatkan NoMethodError.
Anda dapat menggunakan &. untuk menunjuk penerima, maka my_method tidak dipanggil dan hasilnya nol ketika penerima nol. Dalam hal ini, argumen my_method tidak dievaluasi.
Catatan: Meskipun @Santosh memberikan jawaban yang jelas dan lengkap, saya ingin menambahkan lebih banyak latar belakang dan menambahkan catatan penting tentang penggunaannya dengan variabel non instance.
Ini disebut " Operator Navigasi Aman " ( alias "operator rantai opsional", "operator tidak bersyarat", dll .). Matz tampaknya menyebutnya "operator yang kesepian". Itu diperkenalkan di Ruby 2.3 . Ini mengirim metode ke objek hanya jika tidak nil
.
# Call method `.profile` on `user` only if `user` is not `nil`
@user&.profile
# Equivalent to
unless @user.nil?
@user.profile
end
Harap dicatat, kode di atas menggunakan variabel instan. Jika Anda ingin menggunakan operator navigasi yang aman dengan variabel lokal, Anda harus memeriksa apakah variabel lokal Anda ditentukan terlebih dahulu.
# `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
Untuk memperbaiki masalah ini, periksa apakah variabel lokal Anda didefinisikan terlebih dahulu atau setel ke 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 memiliki try
metode yang pada dasarnya melakukan hal yang sama. Ini menggunakan send
metode secara internal untuk memanggil metode. Matz menyarankan agar ini lambat dan ini harus menjadi fitur bahasa bawaan.
Banyak bahasa pemrograman lain memiliki fitur yang serupa: Objective C, Swift, Python, Scala, CoffeeScript, dll. Namun, sintaksis yang umum adalah ?.
(titik pertanyaan). Tapi, sintaks ini tidak bisa diadopsi oleh Ruby. Karena ?
diizinkan dalam nama metode dan dengan demikian, ?.
urutan simbol sudah menjadi kode Ruby yang valid. Sebagai contoh:
2.even?.class # => TrueClass
Itu sebabnya komunitas Ruby harus membuat sintaks yang berbeda. Itu adalah diskusi aktif dan pilihan yang berbeda dianggap ( .?
, ?
, &&
, dll). Berikut adalah daftar beberapa pertimbangan:
u.?profile.?thumbnails
u\profile\thumbnails
u!profile!thumbnails
u ? .profile ? .thumbnails
u && .profile && .thumbnails
# And finally
u&.profile&.thumbnails
Saat memilih sintaks, pengembang melihat berbagai kasus tepi dan diskusi ini cukup berguna untuk dijalani. Jika Anda ingin melihat semua varian dan nuansa operator, silakan lihat diskusi pengantar fitur ini pada pelacak isu Ruby resmi.
.?
dan opsi lain dipertimbangkan, tetapi &.
terpilih! Jadi, hanya &.
akan bekerja.
&.
dan tidak .?
, buruk saya. Memperbarui jawaban saya. Terimakasih atas peringatannya!
user.?profile
harus user&.profile
(tidak dapat mengeditnya sendiri karena hanya mengedit 1 karakter!).
Berhati-hatilah! Meskipun operator navigasi yang aman nyaman, juga bisa menipu Anda untuk mengubah logika Anda dengannya. Saya sarankan menghindari penggunaannya dalam kontrol aliran. Contoh:
str = nil
puts "Hello" if str.nil? || str.empty?
# The above line is different than the below line
puts "Hello" if str&.empty?
Dalam contoh pertama, str.nil?
mengembalikan true
dan str.empty?
tidak pernah dipanggil, menyebabkan puts
pernyataan dieksekusi. Namun dalam contoh kedua, str&.empty?
mengembalikan nil
yang falsey, dan puts
pernyataan itu tidak pernah dieksekusi.
str.nil?
adalah benar (seperti yang Anda katakan) yang berarti str.empty?
tidak akan dipanggil sama sekali (itulah cara kerja ||
operator). Pernyataan Anda selanjutnya benar.
puts "hello" unless str&.present?
(rel hanya untuk metode sekarang?)
digunakan untuk nil check, seperti di kotlin dan swift Misalnya; dengan Object -> Swift dan Kotlin
model = car?.model
model ini bisa nil (Swift) atau null (Kotlin) jika kita belum mendefinisikan nilai model di kelas mobil. kami menggunakan ampersand bukan tanda tanya di ruby
model = car&.model
jika menggunakan car.model tanpa ampersand dan jika model nol, sistem tidak dapat terus berjalan.
try!
metode, bukantry