Let's assume that we need to define a common class for trees (or some other objects we need to have in order to solve a problem). Since our class structure can be quite complex, I prefer to define class methods after its definition. Our common class BaseTree
and one of our specific classes Tree
are
class BaseTree
class BaseNode; end
class NodeA < BaseNode; end
end
class Container
class Tree < BaseTree; end
end
After defining the class structure, we set #initialize
for all nodes.
class BaseTree::BaseNode
def initialize x
p x
end
end
If we test it, then everything is fine
Container::Tree::NodeA.new(1)
# => 1
However, if after that we add a method in the following way
class Container::Tree::NodeA
def some_method; end
end
then it breaks the inheritance between NodeA
and BaseNode
!!
Container::Tree::NodeA.new(2)
# ~> -:30:in `initialize': wrong number of arguments(1 for 0) (ArgumentError)
In order to fix this, we have to define it explicitly
class Container
class Tree < BaseTree
class NodeA < BaseNode; end # explicit inheritance
end
end
class Container::Tree::NodeA
def some_method; end
end
or by the following way
class Container::Tree::NodeA < Container::Tree::BaseNode
def some_method; end
end
class Container::Tree::NodeA < BaseTree::BaseNode
def some_method; end
end
The last way needs to be used only once - the first time we add a method, and we can skip the parent class for later definitions
class Container::Tree::NodeA
def another_method; end
end
After that it works fine, but I find it quite cumbersome, especially if there are a lot of tree types and many different nodes.
Is there a more elegant way to do such definitions?