module Factory
  def factory(c = Proc.new)
    (@__factory ||= []) << c
  end

  def create(*args)
    @__factory.reverse_each do |f|
      return f if f = f.call(*args)
    end if @__factory
    nil
  end

  def inherited(klass)
    factory(klass.method(:create))
    klass.extend(Factory)
    super
  end
end

if $0 == __FILE__
  class A
    extend Factory

    def initialize(obj)
      @obj = obj
    end

    factory(method(:new))
  end

  class B < A
    factory do |obj|
      new(obj) if obj.respond_to?(:split)
    end
  end
  class B1 < B
    factory do |obj|
      new(obj) if obj.respond_to?(:string)
    end
  end
  class C < A
    factory do |obj|
      new(obj) if obj.respond_to?(:readline)
    end
  end

  p A.create("")
  require 'stringio'
  s = StringIO.new
  p A.create(s)
  p B.create(s)
end
