Ruby Module Reference
(by Erik Peterson on November 17th 2008)

In Ruby, I always get confused as to the difference between include and extend with modules, and the effect of class << self inside those. So here's a reference script as to what gets included where:

module ExtendedMod
  def a
    "a"
  end

  class << self
    def b
      "b"
    end
  end
end

module IncludedMod
  def c
    "c"
  end

  class << self
    def d
      "d"
    end
  end
end

class Klass
  def e
    "e"
  end

  class << self
    def f
      "f"
    end
  end
end

class SubKlass < Klass
  def g
    "g"
  end

  # Skip h (ERB::Util.h)
  class << self
    def i
      "i"
    end
  end
end

Klass.extend ExtendedMod
Klass.send(:include, IncludedMod)

[:a, :b, :c, :d, :e, :f, :g, :i].each do |m|
  puts "Klass responds to #{m}? #{Klass.respond_to?(m)}"
  puts "Klass.new responds to #{m}? #{Klass.new.respond_to?(m)}"
  puts "SubKlass responds to #{m}? #{SubKlass.respond_to?(m)}"
  puts "SubKlass.new responds to #{m}? #{SubKlass.new.respond_to?(m)}"
  puts "\n"
end

And the output:

Klass responds to a? true
Klass.new responds to a? false
SubKlass responds to a? true
SubKlass.new responds to a? false

Klass responds to b? false
Klass.new responds to b? false
SubKlass responds to b? false
SubKlass.new responds to b? false

Klass responds to c? false
Klass.new responds to c? true
SubKlass responds to c? false
SubKlass.new responds to c? true

Klass responds to d? false
Klass.new responds to d? false
SubKlass responds to d? false
SubKlass.new responds to d? false

Klass responds to e? false
Klass.new responds to e? true
SubKlass responds to e? false
SubKlass.new responds to e? true

Klass responds to f? true
Klass.new responds to f? false
SubKlass responds to f? true
SubKlass.new responds to f? false

Klass responds to g? false
Klass.new responds to g? false
SubKlass responds to g? false
SubKlass.new responds to g? true

Klass responds to i? false
Klass.new responds to i? false
SubKlass responds to i? true
SubKlass.new responds to i? false

The takeaways? Don't use class << self in modules. Always put class methods and instance methods in different modules. Use extend for class methods and include for instance methods. I had already "learned" this several times, but for some reason I couldn't remember it until I put this thing together.