为什么Ruby改进只修改类而不是模块?

Ruby docs on refinements state

Refinements only modify classes, not modules so the argument must be a class.

为什么是这样?

可以对模块进行猴子修补:

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

我敢肯定这不是一个好主意,但如果你可以限制这种猴子补丁的范围,它可能不会那么糟糕.那你为什么不能呢?

最佳答案 Ruby中的改进旨在处理猴子修补和继承的问题,其目的是将猴子修补限制为特定命名空间中的类的实例.

这些相同的继承问题不以相同的方式应用于模块,因为模块可以使用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命名空间而不使用精简.

由于我们没有使用MyModule的实例(MyModule不是类),因此这种方法非常有效.

类是不可能的,因为除了其他原因,类实例可能不限于使用它们的模块的命名空间…因此,对于类实例,应该使用优化.

点赞