2014-09-07 7 views
5

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

class Person 
    def initialize (first_name, last_name, age) 
     @first_name=first_name 
     @last_name=last_name 
     @age=age 
    end 


    def show() 
     puts @first_name 
     puts @last_name 
     puts @age 
    end 

protected 
    def compare(other) 
    self.instance_variable_get(:@age)<=>other.instance_variable_get(:@age) 
    end 

end 

p1=Person.new("Some", "Body", "99") 
p1.show 
puts "\n" 

p2=Person.new("Who", "Ever", "21") 
p2.show 
puts "\n" 

p1.compare(p2) 

मैं त्रुटि "सुरक्षित विधि` तुलना '# (NoMethodError) के लिए बुलाया " मैं वर्ग के भीतर और बिना से फोन कर की कोशिश की है हो रही है। मैंने यहां बिना किसी संस्करण को चिपकाया। मैंने सोचा कि एक ही कक्षा के अन्य वस्तुओं पर संरक्षित तरीकों को बुलाया जा सकता है। इस त्रुटि का क्या अर्थ है और मैं यहां एक सुरक्षित विधि का सही तरीके से उपयोग कैसे करूं? आपके सहयोग के लिए धन्यवाद।

+0

मैं देख रहा हूँ, इसलिए एक संरक्षित और निजी वर्ग ही नहीं संरक्षित में मतभेद की एक उपवर्ग के साथ प्रयोग के लिए अनुमति देता है मुख्य वर्ग, लेकिन न तो सीधे पहुंच योग्य हैं। बहुत बहुत धन्यवाद, वह मुझे पागल कर रहा था। –

उत्तर

0

आप वर्ग के एक सार्वजनिक विधि में एक संरक्षित विधि कॉल कर सकते हैं ...

class Person 
    def initialize (first_name, last_name, age) 
    @first_name=first_name 
    @last_name=last_name 
    @age=age 
    end 

    def same_age?(other) 
    age == other.age 
    end 

    def show 
    puts @first_name 
    puts @last_name 
    puts @age 
    end 

    protected 

    def age 
    @age 
    end 

end 

p1=Person.new("Some", "Body", "99") 
p1.show 
puts "\n" 

p2=Person.new("Who", "Ever", "21") 
p2.show 
puts "\n" 

# calls a method that calls a protected method 
p1.same_age?(p2) 
=> false 

# but you can't call #age directly... 
begin 
p1.age 
rescue NoMethodError 
    puts "no method error (protected)" 
end 
4

आप protected दृश्यता की गलत दृश्य मिला। Ruby doc कहता है:

दूसरी दृश्यता सुरक्षित है। एक सुरक्षित विधि को कॉल करते समय प्रेषक रिसीवर का उप-वर्ग होना चाहिए या रिसीवर प्रेषक का उप-वर्ग होना चाहिए। अन्यथा कोई NoMethodError उठाया जाएगा।

तो दृश्यता के प्रतिबंध आप क्या सोचा के रूप में इस, नहीं रिसीवर को लागू किया जाता है।

यदि आप उदाहरण विधियों के बाहर compare पर कॉल करना चाहते हैं, तो आपको सार्वजनिक दृश्यता का उपयोग करने की आवश्यकता है। यदि आप कर सकते हैं तो आपको protected संशोधक को हटाने की आवश्यकता है। यह अनुशंसित तरीका है।

यदि कोड ठीक है और आप कोड के उस भाग को संशोधित नहीं कर सकते हैं, तो आप Object#send विधि का उपयोग कर सकते हैं। Object#send दृश्यता बाधा को बाईपास करेगा और यहां तक ​​कि निजी विधियों तक पहुंच भी सकता है।

p1.send(:compare, p2) 

या आप वर्ग को फिर से खोलने और compare वर्ग की दृश्यता बदल सकते:

# you code here 

# reopen and modify visibility 
class Person 
    public :compare 
end 

p1.compare(p2) 
+0

वाह, तो रूबी में वास्तव में एक सुरक्षित विधि का कोई तरीका नहीं है? क्या इसे प्रेषण विधि का उपयोग करने के लिए खराब रूप माना जाता है? पहली जगह क्यों विधि होगी, क्या यह केवल एक्सेस प्रतिबंधों को रोकने के लिए है, या क्या इसके लिए डिज़ाइन किया गया एक और अधिक तर्क या परिस्थिति है? मैं मदद की सराहना करता हूं, मैं बस समझने की कोशिश कर रहा हूं। –

+0

'ऑब्जेक्ट # भेज' वास्तव में इतना बड़ा सौदा नहीं है क्योंकि आप हमेशा बंदर पैच कर सकते हैं और विधि दृश्यता को वैसे भी बदल सकते हैं। यदि आपको गड़बड़ करने के लिए _impossible_ होने के निजी तरीकों की आवश्यकता है, तो रूबी शायद आपके लिए भाषा नहीं है। – ZombieDev