More newbie help with classes and methods please

I posted a question a week or so now which I got some great help with.
Here I am again I’m afraid! What I am now struggling with is how to add
help. What I want is if the user gets the input wrong three times, I’d
like to print to print

Press ‘h’ for help
h
You must enter your age as two digits. i.e if you are twenty five, type 25.

here is the original method:

def check_age
print "Please enter your age: "
age = gets.chomp
target = 18…30
valid = /^\d{2}/

if valid.match(age)
if target === age.to_i
puts ‘Have a nice holiday!’
elsif age.to_i < 18
puts ‘Sorry, too young.’
elsif age.to_i > 30
puts ‘Sorry, too old.’
end
else
puts ‘Incorrect input.’
puts
check_age # Try again
end
end

check_age
gets

Should I create a class and add a ‘show_help’ method (putting the
‘check_age’ method in there as well)? If so, how/where do I call that
method? The method in the above code calls itself. I am a complete
programming newbie by the way.

Maybe we could expand this program to help other new programmers like
myself? The jukebox example in Pickaxe2 seems to fizzle out.

My suggestion would be to add that behavior right when you are getting
the user input. Add a check at the beggining, and keep it out if the
if statement.

Also, I would change the if/elsif statements to a case statement. The
case statement is perfect for what you are trying to do.

Dan

A couple of things:

First, as Daniel already said, why not put the information right in the
loop? However, don’t go recursive there, I’d do a loop instead:

age = 0
target_age = 30…65 # :wink:
while ! target === age
print "Please enter your age: (as two digits): "
result = gets
age = result.chomp.to_i
case age
when age < 30
puts ‘Sorry, too young.’
when age > 75
puts ‘Sorry, too old.’
else
puts ‘Hava a nice holiday!’
return age
end
puts “Remember, age must be entered as two digits, e.g. 35”
end

check_age

Thanks for replies. Just to point out, this code is not meant for
anything in particular, just an example to help me learn ruby. I wanted
to understand recursion better which I now do. Also to understand
ranges and if statements too. What I’m trying to do here is understand
how to branch inside a method.

What are the benefits of using case instead of if? I was going to look
at case a bit later on. The commented code below is what I’ve tried but
it does not work too well. if i type 21 its says ‘have a nice holiday!’
then ‘Incorrect Input’ and prompts me again.


def check_age
print "Please enter your age (or type ‘h’ for help): "
age = gets.chomp
target = 18…30
valid = /^\d{2}/

if age == ‘h’

puts

puts “Example: if you are twenty five, type 25”

puts

check_age

#end

if valid.match(age)
if target === age.to_i
puts ‘Have a nice holiday!’
elsif age.to_i < 18
puts ‘Sorry, too young.’
elsif age.to_i > 30
puts ‘Sorry, too old.’
end
else
puts “Incorrect input.”
puts
check_age # Try again
end
end

check_age
gets

decided to have a go at using the case statement. Why won’t this work?


def double_it
print "Please enter a whole number (or type ‘h’ for help) : "
num = gets.chomp
case num
when num == ‘h’
puts
puts “A whole number is 45 for example, or 12564.”
puts
when num.to_i > 1
num * num
print num.to_s
when num.to_i <= 0
puts “The number must be positive!”
end
end
double_it
gets

Hi –

On Wed, 19 Jul 2006, S Wayne wrote:

A couple of things:

First, as Daniel already said, why not put the information right in the
loop? However, don’t go recursive there, I’d do a loop instead:

age = 0
target_age = 30…65 # :wink:
while ! target === age

s/target/target_age/ Also, “until” is a nicer way to do while ! .

print "Please enter your age: (as two digits): "
result = gets
age = result.chomp.to_i

No need to chomp:

age = gets.to_i

case age
when age < 30

Hang on… Remember that a case statement works like this:

case a
when b

is equivalent to:

if b === a

So what you’ve got is:

if (age < 30) === age

which is going to be either:

if true === age

or

if false === age

Neither of those is ever true when age is an integer, so the test will
never succeed.

A simple if construct will work fine:

if age < 30

elsif age > 75

else

end

check_age
No such method :slight_smile:

David

Hi –

On Wed, 19 Jul 2006, simonh wrote:

 puts

when num.to_i > 1
num * num

What’s that for?

 print num.to_s

when num.to_i <= 0
puts “The number must be positive!”
end
end
double_it
gets

Do you really mean to end with gets?

As for the case statement: have a look at my previous post in this
thread. The problem is that you’re comparing:

num

with the expression:

num == 'h'

Then you’re comparing it with the expression “num.to_i > 1”, and so
on.

A case statement isn’t a good fit here; I’d just use if/else/…/end.

David

Thanks David. Great book by the way. Easier for a beginner than
pickaxe. Ever considered writing a ‘Ruby Projects’ book. Start with
some simple program ideas and build them up to something useful?
Demonstrating all the syntax/conventions of Ruby. I’m happy to put down
a deposit!

Anyway,

if b === a

if false === age

Neither of those is ever true when age is an integer, so the test will
never succeed.

I don’t quite understand I’m afraid. I have a variable I want to check
a number of conditions against. Can’t i do this with the case
expression? Further explanation would be greatly appreciated.

A simple if construct will work fine:

if age < 30

elsif age > 75

else

end

Thats what I thought! What is the main advantage of case over if? Or
when would you be more likely to use one than the other?

check_age

No such method :slight_smile:

I tried wrapping that code in a method and got an error. The main thing
I am trying to understand is where to put the code to print out help.

I end with gets because I’m on Windows which usually shuts the window
immediately unless gets is there.

would this be an example of using case:

case favourite_colour
when white
print ‘white’
when blue
print ‘blue’
when orange
print ‘orange’
end

instead of

var = favourite_colour
if white
print ‘white’
elsif blue
print ‘blue’

end

Hi –

On Wed, 19 Jul 2006, simonh wrote:

would this be an example of using case:

case favourite_colour
when white

Assuming that:

white === favourite_colour

returned a useful value.

if white
print ‘white’
elsif blue
print ‘blue’

end

In the second example you’re not testing var; you’re just testing
the values white and blue. So it’s hard to compare it to the case
statement.

A case statement is basically a wrapper for a bunch of “if” tests –
but the wrapper has very specific behavior: it runs the === method on
each term in succession, with the cased object as the argument:

case a
when b # if b === a

when c,d # if (c === a) || (d === a)

etc.

When you’re doing a comparison that doesn’t have a === equivalent,
you’ll generally need a plain “if”.

David

Hi –

On Wed, 19 Jul 2006, Morton G. wrote:

There are two forms of case block and you have sort of mixed them up. Either
of the following defs of double_it will work. I think the first, using a case
without a target, is probably what you want, but the second, a case with a
target (compares target to pattern with ===), can be made to work, too.

That’s a more thorough answer than mine, since I didn’t think of the
non-targeted case. But I realize that I never think of it, because
I’m not clear on what its advantages are over a bunch of ifs. I guess
with multiple things you can do:

case
when a == 1, a == 2

etc.

David

I view case without a target as a fancy, more compact, and (IMHO)
more readable if-elsif-else block. Because it is more compact and
more readable, I prefer it to if-elsif-else and tend to favor it. I
may be influenced by some years of doing Common Lisp programming – I
was quite fond of cond.

Regards, Morton

There are two forms of case block and you have sort of mixed them up.
Either of the following defs of double_it will work. I think the
first, using a case without a target, is probably what you want, but
the second, a case with a target (compares target to pattern with
===), can be made to work, too.

Hope this helps.

def double_it
print "Please enter a whole number (or type ‘h’ for help) : "
num = gets.chomp
case
when num == ‘h’
puts “A whole number is 45 for example, or 12564.”
double_it
when (n = num.to_i) > 1
puts n * 2 # doubling not squaring
else
puts “Input must be positive number!”
double_it
end
end
double_it
print "Press any key to exit: "
STDIN.getc

def double_it
print "Please enter a whole number (or type ‘h’ for help) : "
num = gets.chomp
case num
when ‘h’
puts “A whole number is 45 for example, or 12564.”
double_it
when /^[^-]\d+/
puts num.to_i * 2 # doubling not squaring
else
puts “Input must be positive number!”
double_it
end
end
double_it
print "Press any key to exit: "
STDIN.getc

Regards, Morton

Hi –

On Wed, 19 Jul 2006, Morton G. wrote:

I view case without a target as a fancy, more compact, and (IMHO) more
readable if-elsif-else block. Because it is more compact and more readable, I
prefer it to if-elsif-else and tend to favor it. I may be influenced by some
years of doing Common Lisp programming – I was quite fond of cond.

I’m not sure about its being more compact, unless you’ve got multiple
conditions in one when. Compare:

if a == 1

elsif a == 2

else

end

with:

case
when a == 1

when a == 2

else

end

In any, ummmm, case… :slight_smile: I’m glad to be reminded of it. Do you use
it when things get more deeply nested?

David

fr morton:

I view case without a target as a fancy, more compact, and (IMHO)

more readable if-elsif-else block. Because it is more compact and

more readable, I prefer it to if-elsif-else and tend to favor it. I

may be influenced by some years of doing Common Lisp

me, too. if i ever need an elsif, i’d go then for the case block. i
never did liked the “elsif” keyword (reminds me too of *nix scripts w
if-fi blocks :). but that is just me :slight_smile:

fr david:

I’m not sure about its being more compact, unless you’ve got multiple

conditions in one when. Compare:

if a == 1

elsif a == 2

else

end

with:

case

when a == 1

when a == 2

else

end

when i use it, i think more in “blocks”. it’s like “there’s a case i’m
handling, and the conditions are…”.

In any, ummmm, case… :slight_smile: I’m glad to be reminded of it. Do you use

it when things get more deeply nested?

i combine it w if-else (no elsif)

kind regards -botp

I try (not always successfully) to avoid deeply nested constructs.
When I can’t escape nesting, rather than directly nesting, I favor
writing something like:

def case_A
case
when …
when …
end
end

def case_B
case
when …
when …
end
end

case
when condition_A then case_A
when condition_B then case_B
end

Regards, Morton

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs