What are the differences between:
module Mod
def here
puts 'child'
end
end
class A
prepend Mod
def here
puts 'parent'
end
end
and
class A
def here
puts 'parent'
end
end
class B < A
def here
puts 'child'
end
end
Or another way to put it: is derivating a class the same as prepending a module of the child's code?
No, it is not. B can only inherit from one class, but Mod can be prepended to many classes. If you were to call super inside B#here, it would always refer to A#here, but inside of Mod#here, it will refer to the #here instance method of whatever class Mod was prepended to:
module Mod
def here
super + ' Mod'
end
end
class A
prepend Mod
def here
'A'
end
end
class B
prepend Mod
def here
'B'
end
end
A.new.here
# => 'A Mod'
B.new.here
# => 'B Mod'
and
class A
def here
'A'
end
end
class B
def here
'B'
end
end
class C < A
def here
super + ' C'
end
end
C.new.here
# => 'A C'
class C < B
def here
super + ' C'
end
end
# TypeError: superclass mismatch for class C
No, it's totally different.
One can prepend as many modules as he wants.
module A
def foo; "A" end
end
module B
def foo; "B" end
end
class C
prepend A, B # Prepending is done by this line
def foo; "C" end
end
### take a look at it!
C.ancestors # => [A, B, C, Object, Kernel, BasicObject]
C.new.foo # => "A"
Ruby implements prepend and inheritance using different ways.
prepend is internally achieved by including modules, which causes the surprising ancestors.
here is another question about prepend which may be helpful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With