I don't understand why this works.
module Base attr_reader :first def setup @first = 1 end end module Addon attr_reader :second def setup #super @second = 2 end end class Test include Base include Addon def initialize(num) @num = num setup end end a = Test.new(1) p a.first p a.second
Basically I have a "base" module, which sets up some stuff. I also have an addon module, which sets up some more stuff if some class wants to include it.
Now when I test it, if I don't have that super call, I get
nil 2
When I do have the super call, I get
1 2
What does super actually do here? It's calling the setup method from the Base module, even when Base and Addon are not related.
This is the first time I've used super in the context of modules. Previously I've always used super calls with classes and thought it was just going up the inheritance tree to find a parent with the same method.
Is including multiple modules also setting up some sort of inheritance tree?
EDIT: for context, the Addon module will never be included without the Base module, and the Base module will always be included before any additional Addon modules.
Ruby uses the super keyword to call the superclass implementation of the current method. Within the body of a method, calls to super acts just like a call to that original method. The search for a method body starts in the superclass of the object that was found to contain the original method.
A Module is a collection of methods, constants, and class variables. Modules are defined as a class, but with the module keyword not with class keyword. Important Points about Modules: You cannot inherit modules or you can't create a subclass of a module. Objects cannot be created from a module.
What is the difference between a class and a module? Modules are collections of methods and constants. They cannot generate instances. Classes may generate instances (objects), and have per-instance state (instance variables).
The Ruby class Class inherits from Module and adds things like instantiation, properties, etc – all things you would normally think a class would have. Because Module is literally an ancestor of Class , this means Modules can be treated like classes in some ways.
Yes, when you include modules, they are injected into inheritance chain
Test.ancestors # => [Test, Addon, Base, Object, Kernel, BasicObject]
Addon
module, when included, redefines existing setup
method from Base
. If you want Base
's version be called, use super
.
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