Reputation: 17470
I have a module like this
module A
module ClassMethods
def a
"a"
end
def b
a
end
end
def self.included(klass)
klass.extend ClassMethods
end
end
I want to factor b
into it's own module because B
s are clearly not A
s. The b
method depends on A
, and I would like the methods defined in A
to be available to B
.
Doing this:
module B
module ClassMethods
extend A
def b
a
end
end
def self.included(klass)
klass.extend(ClassMethods)
end
end
It does not work. Nor does include
. I tried moving include
or extend
as well as the how constants are references. What am I missing here?
Upvotes: 0
Views: 82
Reputation: 4870
Add the extend A
action in the included
callback of the module B
instead of adding it in the ClassMethod
definition, like the following code does:
module A
module ClassMethods
def a
"a"
end
end
def self.included(klass)
klass.extend ClassMethods
end
end
module B
module ClassMethods
def b
a
end
end
def self.included(klass)
klass.extend(ClassMethods)
klass.extend(A)
end
end
class C
include B
end
C.b
# => "a"
Upvotes: 1
Reputation: 3055
I hope I understood what you wanted. I split up module A
and module B
. When I include those in a new class Klass
, I have access to both method a
and method b
, whereas method b
from module B
depends on method a
from module A
:
module A
module ClassMethods
def a
"a"
end
end
def self.included(klass)
klass.extend(ClassMethods)
end
end
module B
module ClassMethods
# include A::ClassMethods here and you can do only 'include B' inside Klass
def b
"Called from B: %s" % a
end
end
def self.included(klass)
klass.extend(ClassMethods)
end
end
class Klass
include A, B
end
p Klass.a # => "a"
p Klass.b # => "Called from B: a"
As I understand you can define the same Module in different places, no need to say include
, extend
or anything. As you see neither Module A
nor Module B
uses those keywords, they both just define ClassMethods
.
Of course, you will have to include module A
wherever you use method b of module B
or else the method call to a
will fail. You can also do include A::ClassMethods
inside B::ClassMethods
, that way you only need to include B
inside Klass
.
Upvotes: 2