2017-08-22 15 views
5

में `try` और` और .` (सुरक्षित नेविगेशन ऑपरेटर) के बीच अंतर है यहाँ मेरी कोड है:क्या रूबी

class Order < Grape::Entity 
    expose :id { |order, options| order.id.obfuscate } 
    expose :time_left_to_review do |order, options| 
    byebug 
    order&.time_left_to_review # ERROR 
    end 
    expose :created_at { |order, options| order.last_transition.created_at } 
end 

# NoMethodError Exception: undefined method `time_left_to_review' for #<Order:0x007f83b9efc970> 

मैंने सोचा था कि &..try के लिए एक शॉर्टकट है, लेकिन मुझे लगता है कि मैं गलत था। क्या कोई मुझे जो खो रहा है उसके बारे में सही दिशा में इंगित कर सकता है?

मुझे लगता है कि यह रूबी से संबंधित नहीं है। अंगूर शायद? हालांकि मुझे नहीं पता कि यह कैसे हो सकता है।

+0

वे ही नहीं हैं आप अंतर [यहां] (के बारे में अधिक पढ़ सकते हैं http://mitrev.net/ruby/2015/11/13 निम्नलिखित उदाहरण पर विचार/ऑपरेटर में गहरे लाल रंग का /) – Redithion

उत्तर

9

&.#try! जैसे #try काम करता है।

और यहाँ #try! (documentation से) का वर्णन है:

#try के रूप में एक ही है, लेकिन अगर प्राप्त नहीं के बराबर नहीं है और कोशिश की विधि लागू नहीं करता है एक NoMethodError अपवाद बढ़ा देंगे।

तो मूल रूप से यह आप nil पर एक विधि को कॉल करने से बचाता है, लेकिन अगर एक वस्तु प्रस्तुत किया है यह हमेशा की तरह उसके विधि कॉल करने की कोशिश करेंगे।

उद्धरण रेल दस्तावेज़ीकरण से है, और इसलिए पर जोर देना महत्वपूर्ण है कि रूबी #try प्रदान नहीं करता है, यह रेल है, या अधिक सटीक ActiveSupport। जबकि सुरक्षित नेविगेशन ऑपरेटर &. रूबी 2.3.0 में प्रस्तुत एक भाषा सुविधा है।

6

try विधि बहुत सी चीजों को अनदेखा करता है, यह सिर्फ इसे एक शॉट देता है और अगर चीजें काम नहीं करती हैं तो इसे एक दिन बुलाती है।

& सशर्त नेविगेशन विकल्प केवलnil ऑब्जेक्ट्स पर ब्लॉक कॉल करेगा। कुछ और मान्य माना जाता है और पूर्ण परिणामों के साथ आगे बढ़ेगा, अपवाद शामिल हैं।

3

मैं यहां थोड़ी देर के लिए पार्टी पहुंच रहा हूं, अन्य उत्तरों ने यह कवर किया है कि यह कैसे काम करता है, लेकिन मैं कुछ ऐसा जोड़ना चाहता था जो अन्य उत्तरों को कवर न किया जाए।

आपका प्रश्न पूछता है try और &.रूबी में अंतर क्या है। रुबी यहाँ कुंजी शब्द है।

सबसे बड़ा अंतर यह है कि try रूबी में मौजूद नहीं है, यह रेल द्वारा प्रदान की जाने वाली एक विधि है। आप अपने आप को यह देख सकते हैं या यदि आप रेल कंसोल में कुछ इस तरह करते हैं:

[1, 2, 3].try(:join, '-') 
#=> "1-2-3" 

लेकिन यदि आप आईआरबी कंसोल में एक ही बात करते हैं, आप मिल जाएगा:

[1, 2, 3].try(:join, '-') 
NoMethodError: undefined method `try' for [1, 2, 3]:Array 

&. है रूबी मानक पुस्तकालय का हिस्सा है, और इसलिए किसी भी रूबी परियोजना में उपलब्ध नहीं है, न केवल रेल।

1

टिप्पणी

सुरक्षित नेविगेशन ऑपरेटर (& में @Redithion से सहमत हैं।)

रूबी

में

परिदृश्य कल्पना कीजिए कि आप एक account एक owner है कि है और आप प्राप्त करना चाहते हैं मालिक address

if account && account.owner && account.owner.address 
... 
end 

यह वास्तव में अत्यधिक शब्द और टाइप करने के लिए कष्टप्रद है: आप निम्नलिखित की तरह कुछ लिखते थे आप सुरक्षित हो सकता है और एक शून्य त्रुटि जोखिम नहीं करना चाहते हैं। - यह या तो पता या nil लौटाता है यदि श्रृंखला के साथ कुछ मूल्य है

if account.try(:owner).try(:address) 
... 
end 

यह एक ही बात सिद्ध: ActiveSupport try विधि है जो एक समान व्यवहार (लेकिन कुछ मुख्य अंतर यह है कि बाद में चर्चा की जाएगी साथ) भी शामिल है nil। पहला उदाहरण झूठी भी लौटा सकता है यदि उदाहरण के लिए owner गलत पर सेट है।

& का उपयोग करना।

हम सुरक्षित नेविगेशन ऑपरेटर का उपयोग कर पिछले उदाहरण पुनर्लेखन कर सकते हैं:

account&.owner&.address 

अधिक उदाहरण

के और अधिक विस्तार में सभी तीन दृष्टिकोण की तुलना करें।

account = Account.new(owner: nil) # account without an owner 

account.owner.address 
# => NoMethodError: undefined method `address' for nil:NilClass 

account && account.owner && account.owner.address 
# => nil 

account.try(:owner).try(:address) 
# => nil 

account&.owner&.address 
# => nil 

अब तक कोई आश्चर्य नहीं है। क्या होगा अगर ownerfalse है (शर्टी कोड की रोमांचक दुनिया में असंभव नहीं है)?

account = Account.new(owner: false) 

account.owner.address 
# => NoMethodError: undefined method `address' for false:FalseClass ` 

account && account.owner && account.owner.address 
# => false 

account.try(:owner).try(:address) 
# => nil 

account&.owner&.address 
# => undefined method `address' for false:FalseClass` 

यहाँ पहले आश्चर्य आता है - &. वाक्य रचना केवल nil छोड़ देता है लेकिन झूठी पहचानता है! यह s1 && s1.s2 && s1.s2.s3 वाक्यविन्यास के बराबर नहीं है।

क्या होगा अगर मालिक मौजूद है लेकिन address का जवाब नहीं देता है?

account = Account.new(owner: Object.new) 

account.owner.address 
# => NoMethodError: undefined method `address' for #<Object:0x00559996b5bde8> 

account && account.owner && account.owner.address 
# => NoMethodError: undefined method `address' for #<Object:0x00559996b5bde8>` 

account.try(:owner).try(:address) 
# => nil 

account&.owner&.address 
# => NoMethodError: undefined method `address' for #<Object:0x00559996b5bde8>` 
उदाहरण नीचे

भ्रामक है और nil&.nil?true लौटना चाहिए।

&. ऑपरेटर का उपयोग करते समय सावधान रहें और nil मानों की जांच करें।

nil.nil? 
# => true 

nil?.nil? 
# => false 

nil&.nil? 
# => nil 

संदर्भ:: here

संबंधित मुद्दे