Friendly Ruby (Quiz Solution)

My solution to the recent Ruby Quiz #91 is friendly.rb, a module that allows a user to interactively add method definitions at runtime.

module Friendly

  def method_missing name
    @_new_methods ||= Hash.new
    unless @_new_methods.has_key? name
      prompt_for_definition name
    end
    eval @_new_methods[name]
  end

  def prompt_for_definition name
    puts "It appears that #{name} is undefined."
    puts "Please define what I should do (end with a blankline):"
    @_new_methods[name] = ""
    while $stdin.gets !~ /^\s*$/
      @_new_methods[name] << $_
    end
  end

  def added_methods
    @_new_methods.keys
  end

  def added_method_definitions
    @_new_methods.map {|k,v|
      s = "def #{k}\n  "
      v.rstrip!
      s << v.gsub("\n", "\n  ")
      s << "\nend"
    }
  end

end

Example usage, in this case just using Friendly to extend the top level object:

irb(main):001:0> include Friendly
=> Object
irb(main):002:0> foo = bar * z
It appears that bar is undefined.
Please define what I should do (end with a blankline):
12

It appears that z is undefined.
Please define what I should do (end with a blankline):
4

=> 48
irb(main):003:0> foo
=> 48
irb(main):004:0> bar
=> 12
irb(main):005:0> z
=> 4
irb(main):006:0> added_methods
=> [:z, :bar]
irb(main):007:0> puts added_method_definitions.join("\n\n")
def z
  4
end

def bar
  12
end
=> nil
irb(main):008:0>

Leave a Reply