Ruby docs on refinements state:
优化只修改类,而不修改模块,因此参数必须是类。
为什么会这样?
可以对模块进行猴子修补:
module MyModule
def my_method
"hello"
end
end
include MyModule
puts my_method # => hello
module MyModule
def my_method
"goodbye"
end
end
puts my_method # => goodbye
我确定这不是一个好主意,但如果你可以限制这种猴子补丁的范围,那可能不会那么糟糕。那你为什么不能?
答案 0 :(得分:2)
模块的细化与类的细化一样有用。考虑如何
module Foobar
refine Enumerable
def all_zero?; all? &:zero? end
end
end
比直接猴子补丁更有礼貌:
module Enumerable
def all_zero?; all? &:zero? end
end
答案 1 :(得分:0)
Ruby中的refine
旨在处理猴子修补和继承问题,其目的是将猴子修补限制为特定命名空间中的类实例。
这些相同的继承问题不会以相同的方式应用于模块,因为模块可以使用mixin扩展或包含在其他模块中(而不是类)。
这将允许通过创建一个新模块来限制猴子修补程序,该模块在其自己的命名空间内扩展和覆盖原始模块。
如果要使用您的示例:
module MyModule
def my_method
"hello"
end
end
include MyModule
puts my_method
# => hello
module MyOtherModule
extend MyModule
puts my_method # will print: hello
def my_method
"goodbye"
end
extend self
puts my_method # will print: goodbye
end
# => hello
# => goodbye
puts my_method
# => hello
正如您所看到的,我们设法将'monkey-patch'限制在MyOtherModule
命名空间而不使用refine
。
由于我们没有使用MyModule
的实例(MyModule
不是一个类),这种方法非常有效。
类不可能这样,因为除了其他原因,类实例可能不限于使用它们的模块的命名空间...因此,对于类实例,应使用refine