You are overriding ParentClass#initialize.
Ruby does not magically invoke overridden methods. That would kind of defeat the point of overriding in the first place: for example, often, the reason why you override a method in a subclass, is that the subclass implementation can make use of its knowledge of the subclass to improve performance. It wouldn't make sense for Ruby to invoke the un-optimized version in addition to the optimized one.
However, another big purpose of overriding is differential code reuse: reusing code by only implementing the difference in behavior. In order to do that, Ruby has the super keyword, which allows you to retry the method lookup starting one level up in the ancestors chain.
Here's what that would look like in your case:
class SubClass < ParentClass
def initialize(*)
super
@retries = 0
end
end
This solves the problem with the un-initialized instance variable.
However, there are several other problems with your code. For example, here:
SubClass.new().run()
You are sending the message new to SubClass without any arguments. By default, Class#new is implemented roughly like this:
class Class
def new(...)
obj = allocate
obj.initialize(...)
obj
end
end
[Technically, initialize is private, so we need to break encapsulation here by using something more like obj.__send__(:initialize, ...).]
In other words, new passes its arguments on to initialize. But you have defined ParentClass#initialize with one mandatory keyword parameter profile:, so theoretically, we need to pass an argument to super … but what should we pass? So, instead, we have defined SubClass#initialize to take arguments and pass them on to ParentClass#initialize.
However, you are passing no arguments to SubClass::new here, that we could pass on, and in fact, it isn't clear what arguments we could pass here.
I would like to help you here, but to be honest, the code simply does not make sense, so I don't see how to fix it. Superclasses must never know about their subclasses, in fact, they typically cannot know about their subclasses: many languages allow you to add subclasses after the fact, and Ruby is no exception. Therefore, a superclass knowing about its subclass is a sign that something in your design is very, very, very wrong.
Also note that the very idea of a "parent instance variable" does not make sense: "parent" refers to the class hierarchy, but instance variables belong to instances … that's why they are called "instance" variables, after all.
SubClassoverwrites initialize, takes no arguments, and does not call super. Change theSubClass#initializetodef initialize(profile:); super; @retries= 0;endand changeParentClass#call_subtoSubClass.new(profile: self.profile).runanother alternative (probably better) is remove initialize fromSubClassand definedef retries; @retries ||= 0; end( you will still have to pass the profile kwarg tonewincall_subthen everything will work as expected.