5

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?

include MyModule

alt
  • 13,357
  • 19
  • 80
  • 120

3 Answers3

12

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:

  • Name spaces
  • Mixins
  • To hold functions

Name Space

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.

Mixin

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

Functions

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
Wayne Conrad
  • 103,207
  • 26
  • 155
  • 191
  • I agree, but I think your third option is really just a perverse alternative implementation of your first. I see no reason why you should ever want to defined a singleton method on a module, unless perhaps if you were also using it as a mixin and wanted to hide that method from instances of the including class. – Borodin Oct 14 '13 at 04:14
  • Your third example is just an example of a singleton class. It would work with any kind of object, not just a module. – Jörg W Mittag Oct 14 '13 at 11:27
  • @Borodin, Defining a module of functions is a common practice. One good example is in the Ruby library itself: http://www.ruby-doc.org/core-2.0.0/Math.html – Wayne Conrad Oct 14 '13 at 15:42
  • Jörg, I don't think so. A singleton class has state, and methods that implicitly operate upon that state. A function does not operate on some object's state. It takes arguments and returns a result. And, if impure, it has side-effects (I/O, etc.). But it is not implicitly bound to some object (other than `main`, but that's really splitting hairs). – Wayne Conrad Oct 14 '13 at 15:48
  • @WayneConrad: Huh? You're defining `foo` in `SomeFunctions`'s singleton class. The fact that `SomeFunctions` is a `Module` is completely irrelevant. It could be any other kind of object. And `foo` is *not* bound to `main`, it's bound to `SomeFunctions`. You could just as well have `def (SomeFunctions = Object.new).foo; puts 'foo' end; SomeFunctions.foo`. – Jörg W Mittag Oct 14 '13 at 23:09
  • @Jörg, Ah, yes, I was wrong about the binding. Thank you for the correction. Still, a function isn't _using_ its implicit binding. I understand now how defining class methods in a function is a sort of singleton. Still, when they are functions, they're not really being used as a singleton would normally be used. They're just functions. – Wayne Conrad Oct 15 '13 at 14:20
  • There is no such thing as a *class method* in Ruby. It's just a *singleton method* of the class object. Actually, there's no such thing as a singleton method either, it's just a regular instance method of the class object's singleton class. And, since every object has a singleton class, not just modules, there's nothing in your third point that is specific to modules. You are not using the fact that `SomeFunctions` is a module in any way. You could do exactly the same with a `String`, an `Array` or any other object. – Jörg W Mittag Oct 15 '13 at 14:29
  • What makes your methods "functions" is the fact that they are referentially transparent and that they don't access `self`, not the fact that they are defined in a module … which they aren't even, they are defined in a singleton class. – Jörg W Mittag Oct 15 '13 at 14:29
1

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 FOOs 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.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
0

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.

Akash
  • 5,153
  • 3
  • 26
  • 42
  • I doubt it. In Ruby terms, Module is a special type of 'class' which cannot be instantiated – Vineeth Pradhan Oct 14 '13 at 03:31
  • Do a `Class.superclass` in irb and it will give `Module`. However doing a `Module.class` will give `Class`. i.e. `Module` is an instance of `Class` and also it's superclass. :) – Akash Oct 14 '13 at 03:44