How to share methods between ruby modules
Here is what I tried:
module A
def self.method1; "method1"; end
def method2; "method2"; end
end
module B; include A; end
B.method1 # => error
B.method2 # => error
B::method1 # => error
B::method2 # => error
I want to avoid copying and pasting equivalent code between two modules. The reason I'm using modules instead of classes h开发者_如何学Pythonere is because I don't need more than one instance of each module, as they simply hold constants (other modules, at this point).
What is the best way to solve this problem?
Plain include
only gives you instance methods (method2
in your particular piece of code). If you want to share module-level methods - extract them to separate module and extend
other modules with it:
module A
extend self # to be able to use A.method1
def method1
"method1"
end
end
module B
extend A
end
B.method1 # => "method1"
It is also possible get module-level methods by include
, but with a little twist, using hook method:
module A
def self.included(other)
other.extend ModuleMethods # this is where the magic happens
end
def instance_method
'instance method'
end
module ModuleMethods
def module_method
'module method'
end
end
extend ModuleMethods # to be able to use A.module_method
end
module B
include A
end
B.module_method #=> "module method"
B.instance_methods #=> [:instance_method]
First of all, please note that A.method2
won't work either. You can create objects including A
(or B
) that will have method2
:
class C
include B # (or A)
end
c = C.new
c.method2
So, for method2
it just works as you intended.
Regarding method1
, it is a singleton method of the object A
and there is no way to inherit it.
精彩评论