fhwang.net

EasyPrompt 0.1.0

If you ever write interactive command-line scripts for Ruby, you might want to take a look at my new library, EasyPrompt. EasyPrompt handles prompts, defaults, and different types of expected input. It also provides a testing facility for mocking out the command-line user.

Here’s an irb session that illustrates what EasyPrompt does:

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(
irb(main):006:0> "Is your name #{ fname } #{ lname }?", true, :boolean
irb(main):007:0> )
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.

blog comments powered by Disqus

« Previous post

Next post »