Refinements only modify classes, not modules so the argument must be a class.
puts my_method # => hello
puts my_method # => goodbye
refine in Ruby is intended to deal with issues of monkey-patching and inheritance, where the intention is to limit the monkey patching to instances of classes within a specific namespace.
These same inheritance issues don't apply to modules in the same way, since modules can be extended or included within other modules (as opposed to classes) using mixins.
This would allow namespace limitation of the monkey-patching by creating a new module which extends and overrides the original within it's own namespace.
If to use your example:
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
As you can see, We managed to limit the 'monkey-patch' to the
MyOtherModule namespace without using
Since we aren't using instances of
MyModule is NOT a class), this approach works perfectly.
The same is not possible with classes since, among other reasons, class instances might not be limited to the namespace of the module within which they are used... Hence, for Class instances,
refine should be used.