Ruby Modules

The Ruby documentation has an awesome description of modules that is worthy of some elaboration. Here’s the description:

A Module is a collection of methods and constants. The methods in a module may be instance methods or module methods. Instance methods appear as methods in a class when the module is included, module methods do not. Conversely, module methods may be called without creating an encapsulating object, while instance methods may not. (See Module#module_function)

This post clarifies the Ruby documentation description by showing ‘module methods’ are actually singleton methods, demonstrating how to call a module’s singleton methods, and also demonstrating how to create a singleton method with the same name and functionality as an instance method.

module M
  def self.hi
    'hi from module method'
  end
end

M.hi # => 'hi from module method'

# another way to call M.hi
M::hi # => 'hi from module method'

Module methods are simply singleton methods for the module object.

module M
  def self.hi
    'hi from module method'
  end
end

M.singleton_methods # => [:hi]

# singleton methods are instance methods
# defined in the singleton class
M.singleton_class.instance_methods(false) # => [:hi]

This blog post has a more detailed explanation of singleton methods.

When a module is included in a class, the singleton methods are ignored and the instance methods become available to the class.

module Calculator
  def self.about
    'I like computation'
  end

  def add(x, y)
    x + y
  end
end

class A
  include Calculator
end

# instance methods are accessible
p A.new.add(3, 4) # => 56

# singleton methods are not included in the class
p A.about # => error

A module’s singleton methods can be called without being included in a class, but a module’s instance methods need to be included in a class to be called.

module Helper
  def self.about
    'i am helpful'
  end

  def full_name(first, last)
    "#{first} #{last}"
  end
end

Helper.about # => 'i am helpful'

# Helper#full_name() can only be called if it's included in a class
Helper.full_name('bob', 'lob') # => error

The Module#module_function() method makes a singleton method with the same name as the instance method, so the singleton method can be called when the module is not included in a class. To exemplify with the prior example, module_function() is used to make full_name() singleton method, so Helper.full_name(‘bob’, ‘lob’) will work.

module Helper
  def full_name(first, last)
    "#{first} #{last}"
  end
  module_function :full_name
end

Helper.full_name('bob', 'lob') # => 'bob lob'

Helper.singleton_methods # => [:full_name]

Here’s an alternate description of modules, inspired from the description in the Ruby documentation:

A Module is a collection of singleton methods, instance methods and constants. Instance methods appear as methods in a class when the module is included, singleton methods do not. Singleton methods may be called without being included in a class, but instance methods need to be included in a class to be called. The Module#module_function method can be used to make a singleton method with the same name as an instance method, so the singleton method can be called without being included in a class.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s