Ruby でクラスメソッドを include する

Ruby でモジュールを include してクラスメソッドを作りたいとします。そのとき、

module Utility
  def self.output(str)
    puts "output: #{str}"
  end
end

class A
  include Utility
end

A.output("Hello!")    #=>undefined method `output' for A:Class (NoMethodError)

はうまくいきません。

ではどうするかというと、こうします。

module Utility
  def output(str)
    puts "output: #{str}"
  end
end

class A
  class << self
    include Utility
  end
end

A.output("Hello!")    #=>"output: Hello!"

 
これはうまくいきます。class << self は特異クラスをオープンします。これはじつは self がクラスA だからで、これがインスタンスならば同様に特異メソッドがオープンされるのです。
 

module Utility
  def output(str)
    puts "output: #{str}"
  end
end

obj = Object.new

class << obj
  include Utility
end

obj.output("Hello!")    #=>"output: Hello!"

 
なお、同じことは Object#extend を使ってもできます(参照)。
 

メタプログラミングRuby 第2版

メタプログラミングRuby 第2版