These days, it seems I hardly have the time for doing fun random hacks. So here I’ve started one, and if anyone finds it interesting, please take it from here and let me know how it turns out.

Loosely based off of AIML, kind of, but not really:

class Conversation

  def initialize(person)
    @person = person
    @response_id = 0
  end  

  attr_reader :response_id

  def say(msg)
    print "#{@person}: "
    @response_id = Response[@response_id].respond_to(msg)
  end 

  class Response

    def self.responses
       @responses ||= {}
    end

    def self.[](id)
      responses[id]
    end  

    def initialize(id)
      @id = id
      self.class.responses[id] = self
      @matchers = []
      @messages = []
    end               

    attr_reader :id,:matchers 

    def when(pattern,id)
      @matchers << [pattern,id]
    end     

    def inherits(arr)
      arr.each do |id|
        @matchers += Response[id].matchers
      end
    end

    def might_say(msg,weight=1)
      weight.times do
        @messages << msg
      end
    end        

    def talk
      puts @messages.sort_by { rand }.pop
    end

    def respond_to(msg)
      @matchers.each do |pattern,id|
        if msg =~ pattern
          Response[id].talk
          return id
        end
      end
      return @id
    end

  end     

end           

def response(id)
  r = Conversation::Response[id] || Conversation::Response.new(id)
  yield(r)
end

UPDATE: Check out this annotated code submitted by a reader.