Hi all,

I've just released EasyPrompt 0.1.0, the initial release of a new 
library that makes it easier to prompt the user interactively in a 
command-line program.

http://easyprompt.rubyforge.org/

EasyPrompt handles defaults, and a few different kinds of expected 
values. Here's a sample irb session:

irb(main):001:0> require 'easyprompt'
=> true
irb(main):002:0> prompt = EasyPrompt.new
=> #<EasyPrompt:0x5a42a0 @stdout=#<EasyPrompt::MockableStdout:0x5a3e04>>
irb(main):003:0> fname = prompt.ask( "What's your first name?" )
What's your first name? John
=> "John"
irb(main):004:0> lname = prompt.ask( "What's your last name?", "Doe" )
What's your last name? [Doe]
=> "Doe"
irb(main):005:0> correct = prompt.ask( "Is your name #{ fname } #{ 
lname }?", true, :boolean )
Is your name John Doe? [y]
=> true

Note that "Doe" is the default value for the last name question, so 
it's what is returned when the user just presses Return. Also, the last 
question is expecting to return a boolean value, so it returns the 
value true instead of a string like "y" or a Fixnum 1.

One cool hack contained in EasyPrompt is the MockCommandLineUser, which 
actually allows you to mock out the human being for purposes of 
testing.

  irb(main):001:0> require 'easyprompt'
  => true
  irb(main):002:0> user = EasyPrompt::MockCommandLineUser.new
  => #<EasyPrompt::MockCommandLineUser:0x595818 @match_count={},
     @mock_stdout=#<StringIO:0x5949b8>, @mock_stdin=#<StringIO:0x595750>,
     @responses={}>
  irb(main):003:0> prompt = EasyPrompt.new
  => #<EasyPrompt:0x57d894 @stdout=#<StringIO:0x5949b8>>
  irb(main):004:0> prompt.ask( "Prepared for this one?" )
  RuntimeError: Can't match "Prepared for this one? "
           from /usr/local/lib/ruby/site_ruby/1.8/easyprompt.rb:79:in 
`match_regexp'
           from /usr/local/lib/ruby/site_ruby/1.8/easyprompt.rb:95:in 
`update'
           from /usr/local/lib/ruby/1.8/observer.rb:185:in 
`notify_observers'
           from /usr/local/lib/ruby/1.8/observer.rb:184:in `each'
           from /usr/local/lib/ruby/1.8/observer.rb:184:in 
`notify_observers'
           from /usr/local/lib/ruby/site_ruby/1.8/easyprompt.rb:128:in 
`gets'
           from /usr/local/lib/ruby/site_ruby/1.8/easyprompt.rb:36:in 
`ask'
           from (irb):4
  irb(main):005:0> user.set_response( /about this one/, "sure!" )
  => ["sure!", nil]
  irb(main):006:0> prompt.ask( "How about this one?" )
  => "sure!"
  irb(main):007:0> user.set_response( /twice/, "no", 1 )
  => ["no", 1]
  irb(main):008:0> prompt.ask( "Can I ask you this twice?" )
  => "no"
  irb(main):009:0> prompt.ask( "Can I ask you this twice?" )
  RuntimeError: Exceeded limit of 1 for (?-mix:twice)
           from /usr/local/lib/ruby/site_ruby/1.8/easyprompt.rb:101:in 
`update'
           from /usr/local/lib/ruby/1.8/observer.rb:185:in 
`notify_observers'
           from /usr/local/lib/ruby/1.8/observer.rb:184:in `each'
           from /usr/local/lib/ruby/1.8/observer.rb:184:in 
`notify_observers'
           from /usr/local/lib/ruby/site_ruby/1.8/easyprompt.rb:128:in 
`gets'
           from /usr/local/lib/ruby/site_ruby/1.8/easyprompt.rb:36:in 
`ask'
           from (irb):9

Ah, if only real users were this easy to control.

Francis Hwang
http://fhwang.net/