2012-07-24 13 views
6

रूबी में, मेरी समझ यह है कि self किसी नंगे विधि कॉल के लिए अंतर्निहित रिसीवर है। हालांकि:यदि रूबी में 'आत्म` हमेशा अंतर्निहित रिसीवर होता है, तो' self.puts 'क्यों काम नहीं करता है?

~: irb 
>> puts "foo" 
foo 
=> nil 
>> self.puts "foo" 
NoMethodError: private method `puts' called for main:Object 

यह क्या बताता है?

मामले में यह किसी भी मदद के लिए:

>> method(:puts).owner 
=> Kernel 
+1

'self.send: puts, "foo"' आज़माएं। आप भेजने के साथ लगभग निजी तरीकों को प्राप्त कर सकते हैं। – DGM

उत्तर

8

निजी पद्धति में एक प्रापक

मुझे लगता है कि नहीं हो सकता है इस सवाल का जवाब यह है: विधि गोपनीयता लागू करने के रूबी का तरीका है कि यह एक स्पष्ट रिसीवर के साथ निजी तरीकों बुला अनुमति नहीं है।

एक उदाहरण:

class Baker 
    def bake_cake 
    make_batter 
    self.use_oven # will explode: called with explicit receiver 'self' 
    end 

    private 
    def make_batter 
    puts "making batter!" 
    end 

    def use_oven 
    puts "using oven!" 
    end 

end 

b = Baker.new 
b.bake_cake 

चूंकि कोई स्पष्ट रिसीवर हो सकता है, आप निश्चित रूप से b.use_oven नहीं कर सकते। और इस तरह विधि गोपनीयता लागू की जाती है।

+0

लेकिन रखता है एक सार्वजनिक विधि, विधि (: रखता है) .owner.public_methods.grep/puts/return [: puts]। एमआरआई रूबी 1.93 पी 1 9 4 – dfang

+0

क्षमा करें, मैं विधि लुकअप भूल गया। self.class.ancestors => [ऑब्जेक्ट, कर्नेल, बेसिक ऑब्जेक्ट] – dfang

+0

@dfang - शायद इसे बाल वर्ग द्वारा निजी रूप से वर्गीकृत किया गया है? अपवाद दिखाने के लिए –

3

आप सही हैं कि self गर्भित रिसीवर जब आप एक स्पष्ट रूप से निर्दिष्ट नहीं है। कारण है कि आपको self.puts करने की अनुमति नहीं है, यह है कि आप एक स्पष्ट रिसीवर के साथ निजी विधियों को कॉल नहीं कर सकते हैं (भले ही वह रिसीवर self है) और त्रुटि संदेश कहता है, puts एक निजी विधि है।

1

आप self. सिंटैक्स का उपयोग करके रूबी में निजी तरीकों तक नहीं पहुंच सकते हैं, या आम तौर पर किसी भी रिसीवर (. के सामने कुछ) का उपयोग करके बोल सकते हैं। यह केवल संरक्षित तरीकों के लिए संभव है।

4

क्योंकि रूबी में गोपनीयता की परिभाषा है: निजी विधियों को केवल एक निहित रिसीवर के साथ बुलाया जा सकता है।

वास्तव में, इस नियम का एक अपवाद है: क्योंकि foo = barहमेशा एक स्थानीय चर बनाता है, आप (बिना self.foo = bar की तरह निजी setters कॉल करने के लिए अनुमति दी जाती है, क्योंकि अन्यथा आप उन्हें सभी पर कॉल करने के लिए सक्षम नहीं होगा प्रतिबिंब का उपयोग कर)।

+1

+1। –

+0

साथ ही प्रतिबिंब का उपयोग करके, आप 'स्वयं' का उपयोग किए बिना 'foo = (bar)' कर सकते हैं। –

+1

@AndrewGrimm: काम नहीं करता है, मैंने अभी कोशिश की है। यह भी समझ में आता है कि काम नहीं करता है, क्योंकि कोष्ठक अभिव्यक्ति समूह के लिए उपयोग किया जा सकता है, इसलिए यह एक पूरी तरह से मान्य स्थानीय परिवर्तनीय असाइनमेंट है। –

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