2013-01-21 14 views
11

में एक झूठी के रूप में कार्य मैं इसएक वस्तु जो रूबी

lol = Klass.new(values) 

unless lol 
    print "false" 
end 

lol.other_method # it is not nil or false, it is a Klass instance! 

क्या करना चाहते हैं लेकिन lol, इस मामले में, नहीं के बराबर या गलत नहीं है कैसे बनाएं, लेकिन एक वस्तु है जो एक झूठी आधारित के रूप में कार्य कर सकते हैं कुछ आंतरिक मूल्य पर। मेरे पास यह विकल्प

lol = Klass.new(values) 

unless lol.to_bool 
    print "false" 
end 

लेकिन यह बदसूरत IMHO है।

मैं झूठी क्लास को बढ़ाने या == के साथ खेलने में सोच रहा था लेकिन सफलता के बिना। कोई विचार?

+0

यह स्पष्ट नहीं है: 'Klass.method (मान) क्या है' क्या यह 'ऑब्जेक्ट # विधि' है? यह तर्क के रूप में एक विधि नाम लेता है और एक विधि देता है, जिसे आप बाद में 'कॉल' कर सकते हैं। – user1852994

+0

इसके बजाय विधि, इस मामले में एक "नया" या एक निर्माता –

उत्तर

9

दुर्भाग्यवश, यह संभव नहीं है।

यह उन परेशान मामलों में से एक है जहां रूबी ऑब्जेक्ट उन्मुख नहीं है। ओओ में, यह एक ऑब्जेक्ट को अनुकरण करने के लिए संभव हो सकता है (असल में, आप किसके बारे में पूछते हैं, यह ओओ के परिभाषा है - याद रखें कि ओओ सिमुलेशन से बाहर आया है), लेकिन यह संभव नहीं है एक ऑब्जेक्ट बनाएं जो false अनुकरण करता है।

ऐसा इसलिए है क्योंकि रूबी में, सशर्त नियंत्रण संरचनाएं भाषा में बेक जाती हैं और संदेश में अनुवाद नहीं करती हैं, जबकि अन्य ओओ भाषाओं में वे केवल नियमित संदेश भेजते हैं (या कम से कम संदेश भेजते हैं, जैसे रुबी में foreach में अनुवाद करता है)। उदाहरण के लिए, स्मालटाक में, Booleans वास्तव में Booleans के चर्च एन्कोडिंग आप लैम्ब्डा पथरी से पता का उपयोग कर लागू किया, और रूबी में अनुवाद किया है कि वे इस जैसे दिखते हैं कर रहे हैं:

:

class FalseClass 
    def if(&block) 
    # do nothing 
    end 

    def if_then_else(then_lambda, else_lambda) 
    else_lambda.() 
    end 

    def not 
    true 
    end 

    def and(&block) 
    self 
    end 

    def or(&block) 
    block.() 
    end 
end 

और TrueClass सिर्फ दर्पण छवि है

class TrueClass 
    def if(&block) 
    block.() 
    end 

    def if_then_else(then_lambda, else_lambda) 
    then_lambda.() 
    end 

    def not 
    false 
    end 

    def and(&block) 
    block.() 
    end 

    def or(&block) 
    self 
    end 
end 

और फिर, जैसे

if 2 < 3 then foo end 
if 2 < 3 then bar else baz end 

कुछ करने के बजाय आप

होता 0
(2 < 3).if { foo } 
(2 < 3).if_then_else(-> { bar }, -> { baz }) 

# using the new keyword arguments in Ruby 2.0, it almost reads like Smalltalk: 
class FalseClass 
    def if(then: -> {}, else: -> {}) 
    else.() 
    end 
end 

class TrueClass 
    def if(then: -> {}, else: -> {}) 
    then.() 
    end 
end 

(2 < 3).if(then: -> { bar }, else: { baz }) 

इस तरह, आप आसानी से संबंधित ऑब्जेक्ट को कार्यान्वित करके false को अनुकरण कर सकते हैं।

अन्य मामलों में, जहां कुछ ऑब्जेक्ट वास्तव में बिल्कुल एक विशिष्ट वर्ग का उदाहरण हो और न केवल सही प्रोटोकॉल बोलें, रूबी एक बच निकलने वाला हैच प्रदान करता है। उदाहरण के लिए, यदि कोई विधि वास्तव में को Array को तर्क के रूप में आवश्यक है, तो पहले यह आपको to_ary पर कॉल करने का प्रयास करेगा, कम से कम आपको अपने ऑब्जेक्ट को Array में बदलने का मौका देगा।to_str, to_int, to_proc, to_float आदि के लिए भी यही है लेकिन कोई समतुल्य to_bool प्रोटोकॉल नहीं है।

+0

धन्यवाद। मैं ऐसा करने की कोशिश कर रहा था: https://github.com/peczenyj/Lazy-Bool - मैं पर्ल बीटीडब्ल्यू चुनता हूं। मैं आपके उदाहरण के बारे में सोचूंगा और कुछ समान रूबी करने की कोशिश करूंगा। –

4

संक्षिप्त उत्तर: यह मत करो। false और nil:

उत्तर है कि रूबी में वहाँ केवल दो चीजें हैं जो के रूप में झूठी का मूल्यांकन कर रहे हैं। सचमुच सबकुछ सत्य के रूप में मूल्यांकन करता है।

कई एप्लिकेशन इस व्यवहार पर निर्भर करते हैं और यदि आप इसे किसी भी तरह से बदलना चाहते हैं तो शायद खराब हो जाएंगे। यह 1 को एक संख्या भी परिभाषित करने जैसा है। यह समस्याएं पैदा करने जा रहा है।

+0

कल्पना करें, सबसे अच्छा विकल्प एक .to_bool को बूलियन संदर्भ में इसका मूल्यांकन करने के लिए जोड़ता है, है ना? –

+2

@TiagoPeczenyj 'एक ऑब्जेक्ट जो कुछ आंतरिक मान के आधार पर झूठी के रूप में कार्य कर सकता है -> बस एक 'झूठी' विधि जोड़ें जो आंतरिक मान का उत्तर देता है और फिर 'lol.false?'। यह बदसूरत नहीं है, लेकिन अगर मैं गलती नहीं करता, तो रूबी बतख टाइपिंग अच्छा है। – user1852994

+0

'झूठी?' विधि जोड़ना थोड़ा अजीब से अधिक लगता है, विशेष रूप से 'false.false' पर विचार करना एक अपरिभाषित विधि होगी। – tadman

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