Lately I bumped into this very interesting post: http://opensoul.org/blog/archives/2011/02/07/concerning-activesupportconcern/ which walks through (and explains) the ActiveSupport::Concern
source code.
A few questions arose, but the most important was this:
Obviously there's a method called append_features
which (by the docs at least) says: "Ruby’s default implementation of this method will add constants, methods, and variables of this module to the base module".
I always thought that module works the same as classes in the sense of the method lookup chain - the only difference is that you can't instantiate objects from it, and that it's not defined as a 'superclass' of this class (since a module is not actually a class). meaning that when a class includes
a module, the module is simply being added as a direct parent in the class's inheritance hierarchy, and as a result, methods which are missing in the including class, will be looked for at the module.
But if that's the case, then what does it mean that append_features
actually "adds methods to the base module", which means that you can actually prevent this behaviour, by overriding this method (which ActiveSupport::Concern
actually does).
Can someone create some order in my head?
Basically, the append_features
is - or should be considered - a deeply internal ruby method.
The Module.include
method is defined (in the "eval.c" file with the name of rb_mod_include
) as a loop, which just calls mod.append_features
(and then mod.included
) for every Module
argument passed to it.
The default append_features
implementation (rb_mod_append_features
in "eval.c" file), calls the rb_include_module
, and this is the method which does the real job.
(Actually the really real job is done by the include_modules_at
few lines below)
It means that you are perfectly right saying that you can prevent or break this basic ruby functionality by overriding the append_features
(at least if you don't call the super
).
The ActiveSupport::Concern
actually calls the super
, just in some cases it postpones the actual call until the "concerned" module is included by some "non-concerned" one.
It's usually better to override the included
method instead of append_features
. The included
is defined as just "return nil"
, thus the probability of breaking anything is smaller. And that is what the documentation of the included
method advices.
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