Extending Ruby Classes with Singleton Methods

Modules can be mixed in to Ruby classes as singleton methods. Mixing in singleton methods is referred to as ‘extending’ a class (as opposed to ‘including’ instance methods in a class).

Singleton methods can be directly included in the singleton class:

module AAA
  def hi
    'hey'
  end
end

class BBB
  class << self
    include AAA
  end
end

p BBB.hi # => 'hey'
p BBB.singleton_methods # => [:hi]

Alternatively, the Object#extend() method can be used to include a module’s methods as singleton methods.

module AAA
  def hi
    'hey'
  end
end

class BBB
  extend AAA
end

p BBB.hi # => 'hey'
p BBB.singleton_methods # => [:hi]

Several Ruby libraries use the following trick to mix in both instance and singleton methods from a single module. This solution leverages the Module#included callback method that is executed whenever the module is included in another module or class.

module ExtraStuff
  def self.included(base)
    # base is the class that invokes include() - CCC in this example
    base.extend(SingletonMethods)
  end

  def instance_meth
    "instance_meth"
  end

  module SingletonMethods
    def sing_meth
      "sing_meth"
    end
  end
end

class CCC
  include ExtraStuff
end

p CCC.new.instance_meth # => "instance_meth"
p CCC.sing_meth # => "sing_meth"

John Nunemaker has an excellent blog post on include vs. extend in Ruby that is a worthwhile read for more on this topic.

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