Yanıtlar:
Buna Güvenli Gezinme İşleci denir. Ruby 2.3.0'da tanıtılan, nesneler üzerinde, Rails'teki yönteme benzer şekilde, nesnenin olabileceğinden nil
(bir undefined method for nil:NilClass
hatadan kaçınma ) endişe etmeden yöntemleri çağırmanıza izin verir .try
Böylece yazabilirsiniz
@person&.spouse&.name
onun yerine
@person.spouse.name if @person && @person.spouse
Gönderen Dokümanlar :
my_object.my_method
Bu my_method mesajını my_object öğesine gönderir. Herhangi bir nesne bir alıcı olabilir, ancak yöntemin görünürlüğüne bağlı olarak bir mesaj göndermek NoMethodError değerini yükseltebilir.
Kullanabilirsin &. bir alıcı atamak için my_method çağrılmaz ve alıcı sıfır olduğunda sonuç sıfır olur. Bu durumda, my_method argümanları değerlendirilmez.
Not: @Santosh açık ve tam bir cevap verse de, biraz daha fazla arka plan eklemek ve örnek olmayan değişkenlerle kullanımı hakkında önemli bir not eklemek istiyorum .
Buna " Güvenli Navigasyon Operatörü " denir ( "İsteğe bağlı zincirleme operatörü", "Boş koşullu operatör" vb. ). Matz buna "yalnız operatör" diyor. Bu edilmiş Ruby 2.3 tanıtıldı . Bir nesneye yalnızca değilse bir yöntem gönderir nil
.
# Call method `.profile` on `user` only if `user` is not `nil`
@user&.profile
# Equivalent to
unless @user.nil?
@user.profile
end
Yukarıdaki kodun örnek değişkenleri kullandığını lütfen unutmayın. Yerel değişkenlerle güvenli navigasyon operatörü kullanmak istiyorsanız, önce yerel değişkenlerinizin tanımlandığını kontrol etmeniz gerekir.
# `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
Bu sorunu gidermek için önce yerel değişkeninizin tanımlanmış olup olmadığını kontrol edin veya bunu nil olarak ayarlayın:
# 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
temelde aynısını yapan bir metoda sahiptir . Bir send
yöntemi çağırmak için dahili olarak yöntemi kullanır . Matz yavaş olduğunu ve bunun yerleşik bir dil özelliği olması gerektiğini öne sürdü .
Diğer birçok programlama dili benzer özelliklere sahiptir: Amaç C, Swift, Python, Scala, CoffeeScript, vb. Ancak, ortak bir sözdizimi ?.
(soru noktası). Ancak bu sözdizimi Ruby tarafından benimsenemedi. Çünkü ?
yöntem adlarında izin ve böylece edildi ?.
sembol dizisi zaten geçerli Yakut kodudur. Örneğin:
2.even?.class # => TrueClass
Bu yüzden Ruby topluluğu farklı bir sözdizimi bulmak zorunda kaldı. Bu aktif bir tartışma oldu ve farklı seçenekler (kabul edildi .?
, ?
, &&
vb.) İşte bazı düşüncelerin listesi:
u.?profile.?thumbnails
u\profile\thumbnails
u!profile!thumbnails
u ? .profile ? .thumbnails
u && .profile && .thumbnails
# And finally
u&.profile&.thumbnails
Sözdizimini seçerken, geliştiriciler farklı uç durumlara baktı ve tartışma ilerlemek için oldukça yararlı. Operatörün tüm varyantlarını ve nüanslarını incelemek istiyorsanız, lütfen resmi Ruby sorun izleyicisi hakkındaki bu özellik tanıtım tartışmasına bakın .
.?
ve diğer seçenekler dikkate alındı, ancak &.
seçildi! Yani, sadece &.
işe yarayacak.
&.
ve olmamalı .?
, benim hatam. Cevabım güncellendi. Söylediğin için teşekkürler!
user.?profile
olmalı user&.profile
(sadece 1 karakterlik bir düzenleme olduğu için kendim düzenleyemedim!).
Dikkatli olmak! Güvenli navigasyon operatörü uygun olsa da, mantığınızı onunla değiştirmek için kendinizi kandırmak da kolay olabilir. Akış kontrolünde kullanımından kaçınılmasını öneriyorum. Misal:
str = nil
puts "Hello" if str.nil? || str.empty?
# The above line is different than the below line
puts "Hello" if str&.empty?
İlk örnekte, ifadenin yürütülmesine neden olan str.nil?
döndürür true
ve str.empty?
asla çağrılmaz puts
. Ancak ikinci örnekte , falsey olan str&.empty?
döndürür nil
ve puts
ifade asla yürütülmez.
str.nil?
doğru olsa da (dediğiniz gibi) bu str.empty?
aslında hiç çağrılmayacak demektir ( ||
operatör bu şekilde çalışır). İfadenizin geri kalanı doğrudur.
puts "hello" unless str&.present?
(sadece mevcut? yöntem için raylar)
kotlin ve swift gibi sıfır kontrolü için kullanılır. Örneğin; Nesneli -> Swift ve Kotlin
model = car?.model
araba modelinde model değerini tanımlamamışsak, bu model sıfır (Swift) veya sıfır (Kotlin) olabilir. yakutta soru işareti yerine o işareti kullanırız
model = car&.model
ve işareti olmadan car.model kullanıyorsanız ve model sıfırsa sistem çalışmaya devam edemez.
try!
yöntem gibi çalışır , değiltry