Reputation: 27852
I have the following code:
class Bike
attr_reader :chain
def initialize
@chain = default_chain
end
def default_chain
raise 'SomeError'
end
end
class MountainBike < Bike
def initialize
super
end
def default_chain
4
end
end
mb = MountainBike.new
p mb.chain
When in the initialization we call super, I would expect the default_chain of the super class to be called, and therefore the Exception to be launched. However, it seems that the Bike class actually goes and calls the default_chain method of the original caller. Why is that?
Upvotes: 0
Views: 195
Reputation: 168101
In object oriented programming, which method is called is solely determined by the receiver and the method name.
initialize
is called on the receiver: MountainBike
instance, for which MountainBike#initialize
matches, and is executed.super
is called, for which Bike#initialize
matches, and is executed.default_chain
is called on the implicit receiver self
, which is the MountainBike
instance. MountainBike#default_chain
matches, and is executed. If Bike#default_chain
were to be called in the last step on the receiver (MountainBike
instance), it would mean that method calling would depend not only on the receiver and the method name, but also on the context. That would make it too complicated, and would defeat the purpose of object oriented programming. Again, the idea of object oriented programming is that method call is solely determined by the receiver and the method name, not the context.
Upvotes: 0
Reputation: 525
As said @BorisStitnicky you need to use singleton_class. For more understanding, in this post you may find info: Understanding the singleton class when aliasing a instance method
Upvotes: 1
Reputation: 27747
The point of putting a same-named method in a sub-class is to overload that method. ie to replace it with your new version.
The code will look at the calling sub-class's version of any method - before it starts looking up the ancestry chain for a method, because the sub-class is the context of the current code.
So even though the method is referred-to in the superclass... the ruby interpreter will still first look at your sub-class's set of method as the main context.
If you also want to call the parent's one - you must use super in your default_chain method too. Alternatively rename the one in the parent class to something else and call it from your superclass only.
Upvotes: 0