开发者

How to share methods between ruby modules

开发者 https://www.devze.com 2023-04-02 04:35 出处:网络
Here is what I tried: module A def self.method1; \"method1\"; end def method2; \"method2\"; end end module B; include A; end

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消