Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to share methods between ruby modules

Tags:

module

ruby

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 here 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?

like image 453
benekastah Avatar asked Jun 29 '26 12:06

benekastah


2 Answers

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]
like image 163
Victor Deryagin Avatar answered Jul 01 '26 07:07

Victor Deryagin


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.

like image 31
undur_gongor Avatar answered Jul 01 '26 07:07

undur_gongor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!