Include Instance & Class Methods from a Module

Adler @ 2016-09-26


Basically in Ruby we can include instance methods and extend class methods from a module. However, sometimes we just want to be lazy that we can do both from one module. Let's say we have a module A.

module A
  def b
    puts "method b from module A"
  end

  def c
    puts "method c from module A"
  end
end

Thus we can include and extend both from it like:

class B
  include A
  extend A
end

B.new.b # => "method b from module A"
B.b     # => "method b from module A"
B.new.c # => "method c from module A"
B.c     # => "method c from module A"

Nevertheless sometimes we want the code clean. For example, we want b to be a class method and c to be an instance method. This can be done with Module#included like the following.

module A
  def self.included(klass)
    def klass.b
      puts "method b from module A"
    end
  end

  def c
    puts "method c from module A"
  end
end

In this way, we will only have to include it once and make them accessible as we want:

class B
  include A
end

B.new.b # => NoMethodError
B.b     # => "method b from module A"
B.new.c # => "method c from module A"
B.c     # => NoMethodError