I have a class Ryte::Theme. If I call included_modules on the class I get back (abbreviated):
[Ryte::Bundleable::Core, Ryte::Bundleable::Validators,
Ryte::Bundleable::Builder, ActiveModel::Validations::HelperMethods,
ActiveModel::Validations, ActiveSupport::Callbacks, Ryte::Bundleable]
Ryte::Theme is pulling in nested modules through a single module Ryte::Bundleable. Here are the relevant class and module definitions:
class Ryte::Theme
include Ryte::Bundleable
end
module Ryte::Bundleable
extend ActiveSupport::Concern
included do
include ActiveModel::Validations
include Ryte::Bundleable::Builder
include Ryte::Bundleable::Validators
include Ryte::Bundleable::Core
end
end
Given this, why is it I receive the following response:
Ryte::Theme.include?(Ryte::Theme::Validators)
=> true
I have not included this additional module (yet).. This is evident in the included_modules response. Is this related to ActiveSupport Concern? I want to be able to include Ryte::Theme::Validators and have it mixin as well but since it thinks it is already included it does not include it ‘again’ (as it shouldn’t if that were true). As such it gets left behind when I add the include to the class definition, like so:
class Ryte::Theme
include Ryte::Bundleable
include Ryte::Theme::Validators # <- Does not load
end
Why is this additional module Ryte::Theme::Validators not mixing in as well?
ADDED
Ok just realized:
1.9.3p194 :005 > Ryte::Bundleable::Validators == Ryte::Theme::Validators
=> true
Odd.. why is this?
UPDATE: This is related to ActiveSupport::Concern (see below).
Try the following:
This happens because of the way the modules and classes are namespaced: when you include
A::B::Cfrom inside ofA::B, the module name is referenced relative to the module itself, which becomes justC(in your case, justValidators). Thus when you includeA::Bin some other classD, rather than including a module namedA::B::C(i.e.Ryte::Bundleable::Validators), ruby includes a module named justC(i.e.Validators). This is whyRyte::Bundleable::Validators == Ryte::Theme::Validatorsevaluates to true.However, with the example above:
So this is where
ActiveSupport::Concernkicks in. Redefine the moduleA::Babove as follows:And you will find that
D.include?(A::B::C)now evaluates to true. I’m honestly not sure why this happens, but it must have something to do with the namespacing above.