I\'m trying to understand the purpose of a Ruby module from a design pattern perspective.
Is a Ruby module essentially just a class that is only initialized once?
A class is a module but a module is not a class. Module
is literally the superclass of Class
. If you know OOP, that's all you need to know.
Ruby modules are best used as namespaces and used in mixins.
A ruby class is a module you can make instances of. Like a class, a module can have methods, but you cannot make an instance of a module. That's the only difference between them.
In practice, modules are commonly used for:
Here's an example of a module used as a name space:
module MyLib
class Foo
end
class Bar
end
end
The full name of these classes is MyLib::Foo and MyLib::Bar. Because they are contained in a namespace (which presumably is unique), the names Foo and Bar cannot conflict with a Foo or Bar defined in your program or in another library.
Here's a module used as a mix-in:
module Mixin
def foo
puts "foo"
end
end
Since you can't make an instance of the Mixin module, you get access to foo by including (mixing in) the module:
class MyClass
include Mixin
end
MyClass.new.foo # => foo
Like a class, a module can hold functions that do not operate on any instance. To do that, you define class methods in the module:
module SomeFunctions
def self.foo
puts "foo"
end
end
A class method defined in a module is just like a class method defined in a class. To call it:
SomeFunctions.foo # => foo
Modules have two uses in Ruby: namespacing of constants and as mixins.
Namespacing of constants simply means that in
FOO = 1
module Bar
FOO = 2
end
module Baz
FOO = 3
end
there are three different FOO
s in three different namespaces: one in the global namespace (which is actually Object
), one in Bar
and one in Baz
.
The more interesting use case is mixins: a mixin is basically a class which is parameterized over its superclass. Or, to put it another way: a mixin is a class that can appear multiple times in the inheritance graph, each time with a different superclass.
Contrast this with multiple inheritance: in multiple inheritance, a class can only appear once in the inheritance graph, but it may have multiple superclasses. A mixin may appear multiple times in the inheritance graph, but each occurrence has only one superclass.
In particular, what happens in Ruby when you mix a module M
into a class C
is that an actual class (a so-called include class) is created (let's call it M′
) whose method table, constant table and variable table pointers point to M
's method table, constant table and variable table, and that class M′
becomes C
's superclass with the old superclass becoming M′
's superclass.