2011-04-20 4 views
6

메서드를 재정의하고 무언가를 수행 한 다음 유물을 남기지 않고 되돌릴 수있는 방법을 찾으려고합니다.ruby ​​- 메서드를 덮어 쓴 다음 되돌리기

저는 이것을 mocha를 사용하여 구현했지만, 프로덕션 응용 프로그램에서는 사용하지 않을 것입니다. 새 메소드에는 매개 변수가 있고 이전 매개 변수에는 매개 변수가 없습니다.

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

관련 문제