क्या करता है &। (एम्परसेंड डॉट) का मतलब रूबी से है?


जवाबों:


205

इसे सेफ नेविगेशन ऑपरेटर कहा जाता है। रूबी 2.3.0 में प्रस्तुत, यह आपको वस्तुओं पर बिना किसी चिंता के विधियों को कॉल करने की सुविधा देता है, जो हो सकता है कि वस्तुएं nil(एक undefined method for nil:NilClassत्रुटि से बचें ), रेल के तरीके के समान हो।try

तो आप लिख सकते हैं

@person&.spouse&.name

के बजाय

@person.spouse.name if @person && @person.spouse

से डॉक्स :

my_object.my_method

यह my_method संदेश my_object को भेजता है। कोई भी वस्तु एक रिसीवर हो सकती है लेकिन संदेश भेजने की विधि की दृश्यता के आधार पर एक NoMethodError बढ़ा सकती है।

तुम उपयोग कर सकते हो &। एक रिसीवर को नामित करने के लिए, तब my_method को आमंत्रित नहीं किया जाता है और जब रिसीवर शून्य होता है तो परिणाम शून्य होता है। उस स्थिति में, my_method के तर्कों का मूल्यांकन नहीं किया जाता है।


13
वास्तव में, यह try!विधि की तरह काम करता है , न किtry
ग्रेज़गोरज़

58

नोट: भले ही @ संतोष ने स्पष्ट और पूर्ण उत्तर दिया हो, मैं कुछ और पृष्ठभूमि जोड़ना चाहूंगा और गैर इंस्टेंस चर के साथ इसके उपयोग के संबंध में एक महत्वपूर्ण नोट जोड़ूंगा ।


इसे " सेफ नेविगेशन ऑपरेटर " ( उर्फ "वैकल्पिक चेनिंग ऑपरेटर", "नल-सशर्त ऑपरेटर", आदि ) कहा जाता है। मैत्ज़ इसे "अकेला ऑपरेटर" कहते हैं। इसे रूबी 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

इस समस्या को ठीक करने के लिए, जांचें कि क्या आपका स्थानीय चर पहले परिभाषित है या इसे शून्य पर सेट करें:

# 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

विधि पृष्ठभूमि

रेलों में वह tryविधि होती है जो मूल रूप से वही करती है। यह sendएक विधि को कॉल करने के लिए आंतरिक रूप से विधि का उपयोग करता है । मतज़ ने सुझाव दिया कि यह धीमा है और यह एक अंतर्निहित भाषा सुविधा होनी चाहिए।

कई अन्य प्रोग्रामिंग भाषाओं में समान विशेषता है: ऑब्जेक्टिव सी, स्विफ्ट, पायथन, स्काला, कॉफीस्क्रिप्ट आदि। हालांकि, एक सामान्य वाक्यविन्यास ?.(प्रश्न डॉट) है। लेकिन, यह वाक्यविन्यास रूबी द्वारा अपनाया नहीं जा सका। क्योंकि ?विधि नामों में अनुमति दी गई थी और इस प्रकार, ?.प्रतीक अनुक्रम पहले से ही एक वैध रूबी कोड है। उदाहरण के लिए:

2.even?.class  # => TrueClass

इसलिए रूबी समुदाय को अलग-अलग वाक्य-विन्यास के साथ आना पड़ा। यह एक सक्रिय चर्चा नहीं हुई और विभिन्न विकल्पों पर विचार किया गया ( .?, ?, &&, आदि)। यहाँ कुछ विचारों की एक सूची है:

u.?profile.?thumbnails
u\profile\thumbnails
u!profile!thumbnails
u ? .profile ? .thumbnails
u && .profile && .thumbnails

# And finally
u&.profile&.thumbnails

सिंटैक्स का चयन करते समय, डेवलपर्स ने विभिन्न किनारे के मामलों को देखा और चर्चा के माध्यम से जाने के लिए काफी उपयोगी है। यदि आप ऑपरेटर के सभी वेरिएंट्स और बारीकियों से गुजरना चाहते हैं, तो कृपया आधिकारिक रूबी इश्यू ट्रैकर पर इस सुविधा परिचय चर्चा को देखें ।


क्या है '।?' ? मुझे लगता है कि यह निर्णय लिया गया था कि इस वाक्यविन्यास का उपयोग करना संभव नहीं होगा। मैं केवल '&' प्राप्त कर सकता हूं। काम करने के लिए।
कीथ बेनेट

2
वास्तव में, जैसा कि मैंने लिखा था .?और अन्य विकल्पों पर विचार किया &.गया था , लेकिन चुना गया था! इसलिए, केवल &.काम करेंगे।
उज्बेकन

ओह, क्षमा करें, मैंने अंत तक अच्छी तरह से नहीं पढ़ा। यदि उदाहरणों का सही सिंटैक्स होता तो क्या यह बेहतर नहीं होता?
कीथ बेनेट

@KeithBennett मैं देख रहा हूं कि आपका क्या मतलब है। मैं अपने पहले उदाहरण में एक टाइपो था। आप सही हैं, यह होना चाहिए &.और नहीं .?, मेरा बुरा। मेरे उत्तर को अपडेट किया। सर उठाने के लिए धन्यवाद!
उज्बोन

@Uzbekjon एज मामले के उदाहरण (विकल्प 1) में अभी भी एक टाइपो है : user.?profileहोना चाहिए user&.profile(इसे स्वयं संपादित नहीं कर सकता क्योंकि यह सिर्फ 1 वर्ण संपादित है!)।
यानिस विली

7

सावधान रहने की जरूरत! यद्यपि सुरक्षित नेविगेशन ऑपरेटर सुविधाजनक है, लेकिन इसके साथ अपने तर्क को बदलने में खुद को रौंदना आसान भी हो सकता है। मैं प्रवाह नियंत्रण में इसके उपयोग से बचने की सलाह देता हूं। उदाहरण:

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बयान निष्पादित किया जाना है। हालांकि दूसरे उदाहरण में, str&.empty?रिटर्न nilजो कि गलत है, और putsविवरण कभी निष्पादित नहीं होता है।


दिलचस्प है, हालांकि तकनीकी रूप से आपके पहले बयान str.nil?में सच है (जैसा कि आप कहते हैं) जिसका मतलब है str.empty?कि वास्तव में बिल्कुल भी नहीं बुलाया जाएगा (यह है कि ||ऑपरेटर कैसे काम करता है)। आपका बाकी कथन सही है।
ओली बेनेट

1
ओह अच्छा पकड़। मुझे यकीन नहीं है कि मैं कैसे चूक गया। मैं अपनी पोस्ट सही कर दूंगा। धन्यवाद!
थॉमस डेरानेक

2
यह सच है कि गलत तर्क का उपयोग करना बहुत आसान है, लेकिन आप यहां विभिन्न चीजों की जांच कर रहे हैं। दूसरी पंक्ति बराबर है अगर str && str.empty? निल नहीं || खाली करें। सुरक्षित नेविगेशन ऑपरेटर अभी भी प्रवाह नियंत्रण के लिए उपयोग करने के लिए पूरी तरह से वैध है puts "hello" unless str&.present?(केवल वर्तमान विधि के लिए रेल)
सैम्पसन क्रॉले

1

यह नील जाँच के लिए उपयोग किया जाता है, जैसे कोटलिन और स्विफ्ट में उदाहरण के लिए; ऑब्जेक्ट के साथ -> स्विफ्ट और कोटलिन

model = car?.model

यह मॉडल शून्य (स्विफ्ट) या नल (कोटलिन) हो सकता है अगर हमने कार के वर्ग में मॉडल मूल्य को परिभाषित नहीं किया है। हम माणिक में प्रश्नवाचक चिन्ह के बजाय उस एम्परसेंड का उपयोग करते हैं

model = car&.model

अगर एम्परसेंड के बिना car.model का उपयोग करें और यदि मॉडल शून्य है तो सिस्टम चालू नहीं रह सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.