I was under the impression that refinements fell outside the usual inheritance scheme in Ruby; that overriding a method within a refinement replaced the original method for all code using the refinement.
But then, I tried this experiment with super
, and it appears that the overridden method gets called:
class MyClass
def my_instance_method
puts "MyClass#my_instance_method"
end
end
module MyRefinement
refine(MyClass) do
def my_instance_method
puts "MyClass#my_instance_method in MyRefinement"
super
end
end
end
using MyRefinement
MyClass.new.my_instance_method
The above code outputs:
MyClass#my_instance_method in MyRefinement
MyClass#my_instance_method
My question is, how? Is the refinement inserted into the class hierarchy in some way?
Based on the documentation, the method lookup for a refinement's built in behaviour is the same as you have observed.
Your assumption was correct that it is not typical inheritance, that can be seen by invoking superclass
class C
def foo
puts "C#foo"
end
end
module M
refine C do
def foo
puts "C#foo in M"
puts "class: #{self.class}"
puts "superclass: #{self.class.superclass}"
super
end
end
end
using M
x = C.new
x.foo
The output:
C#foo in M
class: C
superclass: Object
C#foo