So, as far as I know, the way to simulate/have multiple inheritances in ruby is through modules (if there is another/better pls let me know 👌), so let's say I have the following structure/architecture:
class A
def foo
p "Foo from A"
end
end
module B
def foo
p "Foo from B"
end
end
class C < A
include B
end
c = C.new
c.send('foo')
The code above as a lot of you already know will print Foo from B
, because the send
function will look inside the class C
and since there is no definition for the foo
function it will look for that function within C
ancestors, so my question (maybe not a smart one), is there any way to specify/prioritize an ancestor of C
while calling send
/or a workaround for that behavior (don't want to instantiate the parent class I need it in this way)? I couldn't find anything in the documentation of the send function.
EDITED
The architecture shown above is a legacy code, my intention is to find a workaround in order to not be disruptive with the existing code (that's why I have that architecture)
Thx in advance 👍.
It's unclear why you're trying to do things this way, as you seem to have landed on a desired solution without clearly defining the problem it's meant to solve. Since A and B both have a #foo method, which one is called first will depend on the order in which the method lookup is performed. For example, with your current code:
c.class.included_modules
#=> [B, Kernel]
c.class.ancestors
#=> [C, B, A, Object, Kernel, BasicObject]
In your current code, c.send 'foo'
will call B#foo because it will be the first object in the lookup that can respond_to? :foo
. The only way to change the lookup is to explicitly call A#foo from within the C class, or rewrite A as a module and use Module#prepend to insert it at the front of the lookup before B or C. For example:
module A
def foo; p 'Foo from A'; end
end
module B
def foo; p 'Foo from B'; end
end
class C
include B
prepend A
end
C.ancestors
#=> [A, C, B, Object, Kernel, BasicObject]
C.new.foo
#=> "Foo from A"