2015-09-02 17 views
6

मुझे अक्सर रूबी कोड लिखना पड़ता है जहां मैं एक मूल्य की उपस्थिति की जांच करता हूं और बाद में उस मूल्य के साथ कुछ करता हूं यदि यह मौजूद है। जैसेयदि मूल्य मौजूद है तो कुछ करें

if some_object.some_attribute.present? 
    call_something(some_object.some_attribute) 
end 

मुझे लगता है कि, शांत हो सकता है अगर यह

रूप में लिखा जा सकता है अगर वहाँ रूबी में या हालांकि activesupport इस तरह के एक सुविधा है
some_object.some_attribute.presence { |val| call_something(val) } 
=> the return value of call_something 

किसी को भी पता है?

मैंने इस सुविधा के लिए pull request खोला।

+0

तुम सिर्फ एक एक लाइनर के लिए देख रहे हैं, तो आप एक इनलाइन इस्तेमाल कर सकते हैं अगर कथन: 'call_something (some_object.some_attribute) अगर कुछ_object.some_attribute.present? ' – Sculper

+0

यह' some_attribute' को दो बार आमंत्रित करता है, जो वर्बोज़िटी और प्रदर्शन कारणों के लिए वांछनीय नहीं है (यदि 'some_attribute' IO को आवंटित किया गया है) –

+0

' attr = if some_object। some_attribute.present? call_something (attr) एंड' यह केवल –

उत्तर

11

आप presence और try के संयोजन का उपयोग कर सकते हैं: तर्क के बिना कहा जाता है यह किसी दिए गए ब्लॉक करने के लिए रिसीवर पैदावार जब तक यह nil है

तो try:

'foo'.presence.try(&:upcase) 
#=> "FOO" 

' '.presence.try(&:upcase) 
#=> nil 

nil.presence.try(&:upcase) 
#=> nil 
+0

मैं विभिन्न कारणों से 'कोशिश' को नापसंद करता हूं, लेकिन यहां यह प्रश्न का एक बड़ा जवाब है। – spickermann

+0

अच्छा लेकिन केवल अगर आप रेल पर हैं – nsave

+0

वास्तव में अच्छा - और ऐसा लगता है कि आप 'उपस्थिति' को छोड़ सकते हैं और सीधे 'try'' का आह्वान कर सकते हैं। –

2

आप

do_thing(object.attribute) if object.attribute 

की कोशिश कर सकते जब तक कि विशेषता बूलियन नहीं है यह, आम तौर पर ठीक है। यदि मूल्य गलत है तो यह किस मामले में कॉल नहीं करेगा।

यदि आपकी विशेषता गलत हो सकती है, तो इसके बजाय .nil? का उपयोग करें।

do_thing(object.attribute) unless object.attribute.nil? 
+0

मुझे पता है, लेकिन मैं दो बार 'some_object.some_attribute' को संदर्भित करना टालना चाहता हूं। –

+0

जब तक कि विशेषता वास्तव में एक विधि नहीं है जो कुछ भारी भारोत्तोलन कर रही है, तो इसे दो बार कॉल करने के लिए बहुत कम ओवरहेड है, यह डेटा का एक टुकड़ा है जो पहले से ही स्मृति में संग्रहीत है, इसलिए यह निष्पादित करना तेज़ है। – AJFaraday

+0

आप इसे स्थानीय वैरिएबल पर सेट कर सकते हैं, हालांकि यह वास्तव में केवल दो उपयोगों के लिए बहुत मदद नहीं करता है। या आप कॉलिंग कोड को थोड़ा क्लीनर रखते हुए, अपनी 'call_something' विधि के अंदर शून्य चेक जोड़ सकते हैं। जैसे 'def call_something (attr); अगर attr.nil वापस आते हैं? ; #मुख्य भाग; अंत ' – AJFaraday

0

हालांकि बॉक्स के बाहर ऐसी कोई कार्यक्षमता नहीं है, कोई भी कर सकता है:

some_object.some_attribute.tap do |attr| 
    attr.present? && call_smth(attr) 
end 

दूसरी ओर, रेल इतने सारे monkeypatches प्रदान करता है, एक इस सर्कस के लिए एक संलग्न कर सकता है कि:

class Object 
    def presense_with_rails 
    raise 'Block required' unless block_given? 
    yield self if self.present? # requires rails 
    end 
    def presense_without_rails 
    raise 'Block required' unless block_given? 
    skip = case self 
      when NilClass, FalseClass then true 
      when String, Array then empty? 
      else false 
      end 
    yield self unless skip 
    end 
end 
+0

इसके बजाय http://guides.rubyonrails.org/active_support_core_extensions.html#try का उपयोग क्यों न करें। यह हल्का वजन है, यह अच्छी तरह से परीक्षण और समर्थित है। सालों पहले उन्होंने छोटे हिस्सों में सक्रिय समर्थन तोड़ दिया ताकि हम चेरी चुन सकें जो हम चाहते हैं और एएस रखरखाव पर भरोसा कर सकते हैं ताकि इसे काम जारी रखा जा सके। –

+0

@theTinMan 'try' एक अच्छी पसंद है, मैं सिर्फ एक तकनीक दिखाता हूं जिसका उपयोग किया जा सकता है। मैंने स्टीफन के जवाब को उठाया, बीटीडब्ल्यू। – mudasobwa

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