我正在尝试覆盖这样定义的Rails辅助方法:
class Foo
module Bar
def orig
# orig code
end
alias o orig
module_function :o
module_function :orig
end
end
这样我就可以覆盖orig
和o
并向其中添加功能,如下所示:
def orig
# new code
# super (run orig code)
end
alias o orig
我已经浏览了several different monkey patching methods,但它们似乎没有用。我相信module_function
可以解决这个问题。
有人知道我怎么能做到吗?
答案 0 :(得分:2)
这是一种解决方法。您可以重新打开模块,对原始实例方法进行未绑定的引用,然后重新定义它以调用原始方法(行为有所改变)。
首先是原始定义:
module Foo
def bar(arg)
"self=#{self}, arg=#{arg}"
end
module_function :bar
end
接下来,重新打开并重新定义方法:
module Foo
OrigBarMethod = instance_method(:bar)
def bar(arg)
Foo::OrigBarMethod.bind(self).call(arg + 1)
end
module_function :bar
end
puts Foo.bar(1) # => "self=Foo, arg=2"
我使用bind(self)
,以便原始方法仍然可以使用self
,例如:
class MyClass
include Foo
end
MyClass.new.send(:bar, 1) # => "self=#<MyClass:0x00007fb66a86cbf8>, arg=2"
答案 1 :(得分:2)
如今几乎可以通过继承和Module#prepend
来解决您过去使用猴子修补的任何情况:
module Foo
def bar(arg)
"self=#{self}, arg=#{arg}"
end
module_function :bar
end
module FooExtension
def bar(arg)
super(arg + 1)
end
end
[Foo, Foo.singleton_class].each do |mod|
mod.prepend FooExtension
end
Foo.bar(1) #=> "self=Foo, arg=2"
class MyClass
include Foo
end
MyClass.new.bar(1) #=> "self=#<MyClass:0x00007fb66a86cbf8>, arg=2"