2012-06-22 10 views
15

जाहिर ||=मैं एक विधि को कैसे याद कर सकता हूं जो रूबी में सच, झूठी, या शून्य वापस कर सकता है?

def x? 
    @x_query ||= expensive_way_to_calculate_x 
end 

काम नहीं करेगा अगर यह पता चला है हो सकता है क्योंकि false या nil, तो expensive_way_to_calculate_x अधिक से अधिक चलाने के मिल जाएगा।

वर्तमान में सबसे अच्छा तरीका है मैं जानता हूँ कि एक Array में मूल्य डालने के लिए है:

def x? 
    return @x_query.first if @x_query.is_a?(Array) 
    @x_query = [expensive_way_to_calculate_x] 
    @x_query.first 
end 

वहाँ ऐसा करने का एक और अधिक परंपरागत या कारगर तरीका है?

अद्यतन मुझे एहसास हुआ कि मैं false के अलावा nil memoize करना चाहता था - Andrew Marshall जो एक अन्यथा पूरी तरह से सही जवाब दिया करने के लिए मैं क्षमाप्रार्थी - यह वापस सभी तरह से चला जाता है https://rails.lighthouseapp.com/projects/8994/tickets/1830-railscachefetch-does-not-work-with-false-boolean-as-cached-value करने के लिए।

+0

यह 'शून्य' और 'नल' की संपूर्ण अवधारणा है। – meagar

+0

मैंने अपना प्रश्न संपादित किया क्योंकि मैंने इसे पहली बार सही नहीं किया था - मैं भी शून्य को याद करना चाहता हूं। –

उत्तर

26

स्पष्ट रूप से जाँच लें कि @x_query का मूल्य बजाय nil है:

def x? 
    @x_query = expensive_way_to_calculate_x if @x_query.nil? 
    @x_query 
end 

ध्यान दें कि अगर यह एक उदाहरण चर नहीं था, आप अगर यह भी/बजाय परिभाषित किया गया था की जांच करने के लिए होता है, सभी उदाहरण चर के बाद से nil पर डिफ़ॉल्ट।

अपने अद्यतन कि @x_query को देखते हुए की memoized मूल्य nil हो सकता है, आप defined? बजाय उपयोग कर सकते हैं तथ्य यह है चारों ओर पाने के लिए है कि सभी उदाहरण चर डिफ़ॉल्ट nil रहे हैं:

def x? 
    defined?(@x_query) or @x_query = expensive_way_to_calculate_x 
    @x_query 
end 

ध्यान दें कि a = 42 unless defined?(a) जीता तरह कुछ कर रही ' एक बार पार्सर a =, a को से पहले परिभाषित किया गया है, यह सशर्त तक पहुंचने के बाद से अपेक्षित काम करता है। हालांकि, यह उदाहरण चर के साथ सच नहीं है क्योंकि वे nil पर डिफ़ॉल्ट हैं, जब पार्सर = पर हिट करते समय उन्हें परिभाषित नहीं करता है। भले ही, मुझे लगता है कि यह or या unless का उपयोग करने के लिए unless के साथ defined? के साथ लगातार बनाए रखने के लिए यह एक अच्छा मुहावरे है।

+0

मैं इसे ऊपर उठाने जा रहा हूं क्योंकि यह मेरे प्रश्न के पहले संस्करण का उत्तर है, लेकिन कृपया मेरे संपादन - फिर से क्षमा करें। –

+0

@ सेमसएब्स जहां मैंने आपके अपडेट को अपडेट करने के लिए अपना जवाब अपडेट किया है ':)'। –

+3

'ए = 42 परिभाषित किए जाने तक? (ए)' '' 'शून्य बनाता है, लेकिन '@ ए = 42 परिभाषित किए जाने तक? (@ ए)' 'ए 42' बनाता है, इसलिए 'या' वाक्यविन्यास बिल्कुल आवश्यक नहीं है इस उदाहरण में। –

18

nil के लिए खाते में करने के लिए, defined? का उपयोग देखने के लिए कि चर परिभाषित किया गया है:

def x? 
    return @x_query if defined? @x_query 
    @x_query = expensive_way_to_calculate_x 
end 

defined?nil वापस आ जाएगी अगर चर परिभाषित नहीं किया गया है, या स्ट्रिंग "instance_variable" अन्यथा:

irb(main):001:0> defined? @x 
=> nil 
irb(main):002:0> @x = 3 
=> 3 
irb(main):003:0> defined? @x 
=> "instance-variable" 
संबंधित मुद्दे

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