From: James Edward Gray II Date: 2005-04-27T08:55:16+09:00 Subject: Re: [SOLUTION] HighLine (#29) Here's my solution. I ran out of time, mainly for documentation, but I think I've got something worth showing here. I'm using unit tests, so you can read those (primarily "tc_highline.rb") to see how my module works. It covers the basics in the quiz and is pretty open for new additions. The killer feature is the type you specify in to ask(). It's really powerful in that it can take a Proc that does the conversion to whatever you like. agree(), my version of ask_if() from the quiz, is implemented in these terms: def agree( yes_or_no_question ) ask( yes_or_no_question, lambda { |a| a =~ /\AY(?:es)?\Z/i ? true : false } ) end Here are some other examples from my test cases: def test_membership @input << "112\n-541\n28\n" @input.rewind answer = @terminal.ask("Tell me your age.", Integer) do |q| q.member = 0..105 end assert_equal(28, answer) end def test_reask number = 61676 @input << "Junk!\n" << number << "\n" @input.rewind answer = @terminal.ask("Favorite number? ", Integer) assert_kind_of(Integer, number) assert_instance_of(Fixnum, number) assert_equal(number, answer) assert_equal( "Favorite number? " + "You must enter a valid Integer.\n" + "? ", @output.string ) # ... end def test_type_conversion # ... @input.truncate(@input.rewind) number = 10.5002 @input << number << "\n" @input.rewind answer = @terminal.ask( "Favorite number? ", lambda { |n| n.to_f.abs.round } ) assert_kind_of(Integer, answer) assert_instance_of(Fixnum, answer) assert_equal(11, answer) # ... @input.truncate(@input.rewind) @input << "6/16/76\n" @input.rewind answer = @terminal.ask("Enter your birthday.", Date) assert_instance_of(Date, answer) assert_equal(16, answer.day) assert_equal(6, answer.month) assert_equal(76, answer.year) # ... @input.truncate(@input.rewind) @input << "gen\n" @input.rewind answer = @terminal.ask("Select a mode: ", [:generate, :run]) assert_instance_of(Symbol, answer) assert_equal(:generate, answer) end def test_validation @input << "system 'rm -rf /'\n105\n0b101_001\n" @input.rewind answer = @terminal.ask("Enter a binary number: ") do |q| q.validate = /\A(?:0b)?[01_]+\Z/ end assert_equal("0b101_001", answer) end I had a lot of fun working on this library and may just keep working on it to see if I can't turn it into something genuinely useful. You can load my library two different ways: # This first way loads the class system, useful if you want to manage many HighLine # objects, say for socket work. require "highline" # Or you can take the easy out an import methods to the top level. require "highline/import" You can find my code here: http://rubyquiz.com/highline.zip Enjoy. James Edward Gray II