2011-04-20 17 views
6

वापस लाएं मैं एक तरीका खोजने की कोशिश कर रहा हूं कि मैं एक विधि को ओवरराइड कर सकता हूं, कुछ कर सकता हूं, और उसके बाद किसी भी कलाकृतियों को छोड़ दिए बिना वापस लौटा सकता हूं।रूबी - ओवरराइड विधि और फिर

मैंने इसे मोचा का उपयोग करके कार्यान्वित किया है लेकिन जाहिर है कि यह एक उत्पादन ऐप में उड़ान भरने वाला नहीं है। ध्यान दें कि नई विधि में पैरामीटर हैं और पुराना कोई नहीं है।

उदाहरण के रूप में

require 'rubygems' 
require 'mocha' 

class Example 

    def to_something 
    self.stubs(:attribs => other(1)) 
    r = attribs_caller 
    self.unstub(:attribs) 
    r 
    end 

    def other(int) 
    {"other" => int } 
    end 

    def attribs_caller 
    attribs 
    end 

    def attribs 
    {"this" => 1 } 
    end 

end 

a1 = Example.new 

puts a1.attribs_caller #=> this1 
puts a1.to_something #=> other1 
puts a1.attribs_caller #=> this1 

उत्तर

2

ऐसा करने के लिए, एक अतिरिक्त विधि बनाने के बिना एक और तरीका है, इस प्रकार यह है:

class Foo 
    def bar 
    :old_method 
    end 
end 

Foo.new.foo # => :old_method 

$old_method = Foo.new.method(:bar) 

class Foo 
    def bar 
    :new_method 
    end 
end 

Foo.new.foo # => :new_method 

class Foo 
    define_method($old_method.name, &$old_method) 
end 

Foo.new.foo # => :old_method 

मुझे लगता है कि यह एक उपनाम विधि का उपयोग कर से बेहतर है । रूबी विधियों में, वस्तुएं भी हैं। मैं कक्षा के साथ वस्तु (विधि) के संगठन को नष्ट करने से पहले वस्तु का संदर्भ लेता हूं। एक ही विधि जोड़ने के बाद। यदि आप वर्ग से विधि को हटाने के लिए undef कीवर्ड का उपयोग करते हैं तो यह भी काम करता है। बुरी बात यह है कि विधि के संदर्भ में आपको कक्षा का उद्देश्य होना चाहिए।

7
class String 
    alias orig_reverse reverse 
    def reverse(n) 
    'fooled you. '*n 
    end 
end 

puts "ab".reverse(2) 
#=> fooled you fooled you 

# clean up: 
class String 
    alias reverse orig_reverse 
    remove_method(:orig_reverse) 
end 

puts "ab".reverse #=> ba 
+0

अच्छा, इस के साथ एक मुद्दा यह तथ्य है कि नई विधि गतिशील है और कुछ पैरा की आवश्यकता है। हालांकि मैं इस विधि को गतिशील रूप से परिभाषित कर सकता हूं। मैंने इसे प्रतिबिंबित करने के लिए उदाहरण अपडेट किया। – stellard

+0

ऐसा लगता है कि सही पैरामीटर ऑर्डरिंग 'alias alias_name original_name' है, न कि दूसरी तरफ ... – vemv

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