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