[QUIZ] HighLine (#29)

R

Ruby Quiz

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2. Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3. Enjoy!

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

When you stop and think about it, methods like gets(), while handy, are still
pretty low level. In running Ruby Quiz I'm always seeing solutions with helper
methods similar to this:

# by Markus Koenig

def ask(prompt)
loop do
print prompt, ' '
$stdout.flush
s = gets
exit if s == nil
s.chomp!
if s == 'y' or s == 'yes'
return true
elsif s == 'n' or s == 'no'
return false
else
$stderr.puts "Please answer yes or no."
end
end
end

Surely we can make something like that better! We don't always need Rails or a
GUI framework and there's no reason writing a command-line application can't be
equally smooth.

This week's Ruby Quiz is to start a module called HighLine (for high-level,
line-oriented interface). Ideally this module would eventually cover many
aspects of terminal interaction, but for this quiz we'll just focus on getting
input.

What I really think we need here is to take a page out of the optparse book.
Here are some general ideas:

age = ask("What is your age?", Integer, :within => 0..105)
num = eval "0b#{ ask( 'Enter a binary number.',
String, :validate => /^[01_]+$/ ) }"

if ask_if("Would you like to continue?") # ...

None of these ideas are etched in stone. Feel free to call your input method
prompt() or use a set of classes. Rework the interface any way you like. Just
be sure to tell us how to use your system.

The goal is to provide an easy-to-use, yet robust method of requesting input.
It should free the programmer of common concerns like calls to chomp() and
ensuring valid input.
 
F

Francis Hwang

Hi,

Not that this necessarily mitigates the educational value of this Quiz,
but: EasyPrompt sort of does what you're saying below.

http://easyprompt.rubyforge.org/

Example:

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

It's mockable, too! Everything must be mockable.



The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this
quiz until
48 hours have passed from the time on this message.

2. Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3. Enjoy!

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
=-=-=-=-=-=

When you stop and think about it, methods like gets(), while handy,
are still
pretty low level. In running Ruby Quiz I'm always seeing solutions
with helper
methods similar to this:

# by Markus Koenig

def ask(prompt)
loop do
print prompt, ' '
$stdout.flush
s = gets
exit if s == nil
s.chomp!
if s == 'y' or s == 'yes'
return true
elsif s == 'n' or s == 'no'
return false
else
$stderr.puts "Please answer yes or no."
end
end
end

Surely we can make something like that better! We don't always need
Rails or a
GUI framework and there's no reason writing a command-line application
can't be
equally smooth.

This week's Ruby Quiz is to start a module called HighLine (for
high-level,
line-oriented interface). Ideally this module would eventually cover
many
aspects of terminal interaction, but for this quiz we'll just focus on
getting
input.

What I really think we need here is to take a page out of the optparse
book.
Here are some general ideas:

age = ask("What is your age?", Integer, :within => 0..105)
num = eval "0b#{ ask( 'Enter a binary number.',
String, :validate => /^[01_]+$/ ) }"

if ask_if("Would you like to continue?") # ...

None of these ideas are etched in stone. Feel free to call your input
method
prompt() or use a set of classes. Rework the interface any way you
like. Just
be sure to tell us how to use your system.

The goal is to provide an easy-to-use, yet robust method of requesting
input.
It should free the programmer of common concerns like calls to chomp()
and
ensuring valid input.

Francis Hwang
http://fhwang.net/
 
B

Bill Atkins

------=_Part_5179_7322146.1114181187873
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Is using a class instead of a module allowed?

=20
The three rules of Ruby Quiz:
=20
1. Please do not post any solutions or spoiler discussion for this quiz= =20
until
48 hours have passed from the time on this message.
=20
2. Support Ruby Quiz by submitting ideas as often as you can:
=20
http://www.rubyquiz.com/
=20
3. Enjoy!
=20
=20
-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-= =3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D=
-=3D-=3D-=3D
=20
When you stop and think about it, methods like gets(), while handy, are= =20
still
pretty low level. In running Ruby Quiz I'm always seeing solutions with= =20
helper
methods similar to this:
=20
# by Markus Koenig
=20
def ask(prompt)
loop do
print prompt, ' '
$stdout.flush
s =3D gets
exit if s =3D=3D nil
s.chomp!
if s =3D=3D 'y' or s =3D=3D 'yes'
return true
elsif s =3D=3D 'n' or s =3D=3D 'no'
return false
else
$stderr.puts "Please answer yes or no."
end
end
end
=20
Surely we can make something like that better! We don't always need Rails= =20
or a
GUI framework and there's no reason writing a command-line application=20
can't be
equally smooth.
=20
This week's Ruby Quiz is to start a module called HighLine (for=20
high-level,
line-oriented interface). Ideally this module would eventually cover many
aspects of terminal interaction, but for this quiz we'll just focus on=20
getting
input.
=20
What I really think we need here is to take a page out of the optparse=20
book.
Here are some general ideas:
=20
age =3D ask("What is your age?", Integer, :within =3D> 0..105)
num =3D eval "0b#{ ask( 'Enter a binary number.',
String, :validate =3D> /^[01_]+$/ ) }"
=20
if ask_if("Would you like to continue?") # ...
=20
None of these ideas are etched in stone. Feel free to call your input=20
method
prompt() or use a set of classes. Rework the interface any way you like.= =20
Just
be sure to tell us how to use your system.
=20
The goal is to provide an easy-to-use, yet robust method of requesting=20
input.
It should free the programmer of common concerns like calls to chomp() an= d
ensuring valid input.
=20
=20


--=20
Bill Atkins

------=_Part_5179_7322146.1114181187873--
 
B

Bill Atkins

------=_Part_5235_16065989.1114181803442
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Disregard. :)

=20
Is using a class instead of a module allowed?
=20
On 4/22/05 said:
=20
The three rules of Ruby Quiz:
=20
1. Please do not post any solutions or spoiler discussion for this quiz= =20
until=20
48 hours have passed from the time on this message.
=20
2. Support Ruby Quiz by submitting ideas as often as you can:
=20
http://www.rubyquiz.com/
=20
3. Enjoy!
=20
=20
-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=
=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D=
-=3D-=3D-=3D-=3D
=20
When you stop and think about it, methods like gets(), while handy, are= =20
still
pretty low level. In running Ruby Quiz I'm always seeing solutions with= =20
helper=20
methods similar to this:
=20
# by Markus Koenig
=20
def ask(prompt)
loop do
print prompt, ' '
$stdout.flush
s =3D gets
exit if s =3D=3D nil
s.chomp!
if s =3D=3D 'y' or s =3D=3D 'yes'
return true
elsif s =3D=3D 'n' or s =3D=3D 'no'
return false
else
$stderr.puts "Please answer yes or no."
end
end
end
=20
Surely we can make something like that better! We don't always need=20
Rails or a
GUI framework and there's no reason writing a command-line application= =20
can't be=20
equally smooth.
=20
This week's Ruby Quiz is to start a module called HighLine (for=20
high-level,
line-oriented interface). Ideally this module would eventually cover=20
many
aspects of terminal interaction, but for this quiz we'll just focus on= =20
getting=20
input.
=20
What I really think we need here is to take a page out of the optparse= =20
book.
Here are some general ideas:
=20
age =3D ask("What is your age?", Integer, :within =3D> 0..105)
num =3D eval "0b#{ ask( 'Enter a binary number.',=20
String, :validate =3D> /^[01_]+$/ ) }"
=20
if ask_if("Would you like to continue?") # ...
=20
None of these ideas are etched in stone. Feel free to call your input= =20
method
prompt() or use a set of classes. Rework the interface any way you like= =20
Just=20
be sure to tell us how to use your system.
=20
The goal is to provide an easy-to-use, yet robust method of requesting= =20
input.
It should free the programmer of common concerns like calls to chomp()= =20
and
ensuring valid input.=20
=20
=20
=20
=20
--=20
Bill Atkins=20




--=20
Bill Atkins

------=_Part_5235_16065989.1114181803442--
 
J

James Edward Gray II

Ruby Quiz said:
What I really think we need here is to take a page out of the
optparse book.
Here are some general ideas:

age = ask("What is your age?", Integer, :within => 0..105)
num = eval "0b#{ ask( 'Enter a binary number.',
String, :validate => /^[01_]+$/ ) }"

Do not ever do that.

irb(main):004:0> Integer("0b1011")
=> 11
irb(main):005:0> "1011".to_i(2)
=> 11

irb(main):006:0> "foo\nbar" =~ /^foo$/
=> 0

I'm not exactly sure what you're trying to show here. Even 0 would be
a fine binary number. However, the point was that I have created a
safe eval() because ask() should not return anything that doesn't
validate.

Obviously, using Integer() is better style though.

James Edward Gray II
 
B

Bill Kelly

From: "James Edward Gray II said:
num = eval "0b#{ ask( 'Enter a binary number.',
String, :validate => /^[01_]+$/ ) }"

Do not ever do that.

irb(main):004:0> Integer("0b1011")
=> 11
irb(main):005:0> "1011".to_i(2)
=> 11

irb(main):006:0> "foo\nbar" =~ /^foo$/
=> 0

I'm not exactly sure what you're trying to show here. Even 0 would be
a fine binary number. However, the point was that I have created a
safe eval() because ask() should not return anything that doesn't
validate.

I think he meant along the lines of:

irb --simple-prompt
p "looks ok!" if "01010\nsystem('rm -rf /')" =~ /^[01_]+$/
"looks ok!"


Regards,

Bill
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top