Here's my solution:
http://www.dave.burt.id.au/ruby/highline.rb
It's inspired a fair bit by OptParse, and I tried to make it very flexible
and smart in how it accepts options. The code features a little
meta-programming (so you can do "retries 1" or "validation 1..10" in a block
passed to the Prompt.new), optional named arguments, and inference of
arguments' meaning by class somewhat like OptParse#on does.
It's not as easily mockable as EasyPrompt - you would have to do something
tricky like this:
class Prompt
def print(*args)
my_alternate_output_stream.print *args
end
def gets
my_alternate_input_stream.gets
end
end
I think the code you write to use it is cleaner and more straighforward than
the examples from the quiz question and the EasyPrompt doco. Here are those
examples and more:
# Example usage from the Quiz
age = ask("What is your age?", Integer, 0..105 )
num = ask('Enter a binary number.') {|s| not s =~ /[^01]/ }.to_i(2)
if ask("Would you like to continue?", TrueClass) # ...
# Example usage from EasyPrompt documentation
irb(main):003:0> fname = prompt.ask( "What's your first name?" )
What's your first name? John
=> "John"
irb(main):004:0> lname = ask("What's your last name?", "Doe")
What's your last name? [Doe]
=> "Doe"
irb(main):005:0> ok = ask("Is your name #{ fname } #{ lname }?", TrueClass)
Is your name John Doe? [Yn]
=> true
# Extra examples
s = ask
i = ask("How many strikes will be allowed?", 3, 0..(1.0/0.0))
s = ask("Give me a word with "foo" in it:", /foo/)
i = ask("Give me a number divisible by 3:", Integer) {|i| i % 3 == 0 }
a = ask("Give me three or more numbers:", Array) do |x|
x.each {|n| Float(n) }
x.size >= 3 or puts "I need more things than that!"
end.map {|n| n.to_f }
# And you can also get a reusable Prompt object:
p = Prompt.new("A word with foo in it?") do
validation /foo/i
default "Foo"
end
p = Prompt.new("A word with foo in it?", "Foo", /foo/i)
s = p.ask