Here is my solution for the Madlibs Ruby Quiz. I tried to keep the
process of asking the questions separate from assembling the completed
madlib with the answers.

class Madlib
  
  # Given the madlib text as a string, builds a list of questions and
  # a map of questions to "blanks"
  def initialize(txt)
    @questions = []
    @story_parts = []
    @answer_list = []
    @answers = []
    
    stored = {}

    txt.split(/\((\([^)]*\))\)/).each do |item|
      if item[0] == ?(
        item = item[1..-2].gsub("\n", ' ')
        if item.index(':')
          name, question = item.split(':')
          stored[name] = @questions.length
          @questions << question
        else
          name, question = item, item
        end
        @answer_list << (stored[name] || @questions.length)
        @questions << question unless stored[name]
      else
        @story_parts << item
      end
    end
  end
  
  # Calls a block with the index and text of each question
  def list_questions(&block)
    @questions.each_index do |i|
      yield(i, @questions[i])
    end
  end

  # Stores the answer for a given question index
  def answer_question(i, answer)
    @answers[i] = answer
  end

  # Returns a string with the answers filled-in to their respective blanks
  def show_result
    real_answers = @answer_list.collect {|i| @answers[i]}
    @story_parts.zip(real_answers).flatten.compact.join
  end
end

# Example that reads the madlib text from a file specified on the
# command line

madlib = Madlib.new(IO.read(ARGV.shift))
answers = []
madlib.list_questions do |i, q|
  print "Give me " + q + ": "
  answers[i] = gets.strip
end
answers.each_index {|i| madlib.answer_question(i, answers[i]) }
puts madlib.show_result

--Sean McCardell