Ruby Modules

Modules can be used with different goals:

namespacing

To define constants:

module Foo
  Bar = 123
end

puts Foo::Bar

Or methods

module Foo
  def self.greet # Note the self
    puts "Hi!"
  end
end

Foo::greet
Foo.greet # Both syntaxes are ok

Mixins

To add functionality to classes:

module Foo
  def greet
    puts "Hi!"
  end
end

class Bar
  include Foo
end

Bar.new.greet

The include keyword might let you think the interpreter will just add the code contained in the module in the class definition, but actually it will create a singleton class that points to the module methods.

To add some class methods we could use something like this:

module Foo
  def greet
    puts "Hi!"
  end
end

class Bar
  class << self
    include Foo
  end
end

Bar.greet

But the extend method does exactly this:

module Foo
  def greet
    puts "Hi!"
  end
end

class Bar
  extend Foo
end

Bar.greet

It includes the module to the singleton class.

If we want to combine the two steps the cleanest way is this one:

module Bar
  def self.included(base)
    base.extend ClassMethods
  end
  
  def an_instance_method
    puts "Hi instance!"
  end
  
  module ClassMethods
    def a_class_method
      puts "Hi class!"
    end
  end
end

class Foo
  include Bar
end

Foo.new.an_instance_method 
Foo.a_class_method