#!/usr/bin/ruby
N = 42
print "Guess what number I'm thinking of? "
v = gets.to_i
abort "Only positive numbers" if v < 0
if v == N
puts "Well Done!"
else
print "Keep Trying!\nThe number is ", (v < N) ? "HIGHER" : "LOWER", "\n"
# If we have failed, we add a hint
h = (v-N).abs
print "HINT: "
if h < 5 then puts ("TOO HOT!")
elsif h < 10 then puts ("HOT")
elsif h < 15 ; puts ("WARM")
else ; puts "COLD" end
endRuby is very complete when it comes to conditional expressions. It
provides a ternary operator like C/Perl and if-elsif-else
constructs like Perl-Python. It also allows us to define one-line
conditionals in the Perl style and the Python style… Basically all the
options we can think of.
Ruby does not require us to enclose our conditions within parentheses, although there is no problem with doing so. In that case, as happens with Python, it is one more operator to force the precedence of the logical operation to be performed.
DID YOU KNOW…
Ruby is a properly object-oriented language. This means that everything in Ruby is an object. It may seem strange the way we invoke the
absfunction. Of course, because it is really a method of theNumericclass.The variables
vandnactually contain objects of the classNumeric. By subtracting them, we are getting a new object of the same class and since that class defines a methodabs… we simply call it. In Ruby we can write things like:-55.abs
As you can see, when we write the if, elsif
or else instructions on a single line, we must separate the
condition from the instruction to be executed, either using the keyword
then or the character ;.
In the example program, observe the end at the end of
the last line. This end ends the block started with the
first if. Similarly, the internal block in which we chain
several ifs to show the hint, follows the same structure,
only that we wrote the final end on the same line as the
else.
I’M A NEWBIE
You may have noticed the line
v = gets.to_iThis chaining of methods is common in strongly object-oriented languages like Ruby. It is also common to see it in Python and Java. Let’s see what’s happening.
The method
getsreturns an object of typestring. Thisstringobject provides a methodto_i, which generates a new object of type numeric initialized with the value contained in the string.We will see many more constructions like this in the following chapters
Ruby offers a variant of the switch statement that is
more powerful than the one provided by the C language and derivatives,
allowing us to use strings, ranges, or even regular expressions.
case variable
when NUMBER..NUMBER then code
when /regex/
code
when Class1, Class2
code
when "String"
code
else
print "Default value"
endThe syntax is very similar to that of the switch
statement in C, but using different keywords and allowing us to use much
more complex expressions for the cases. The code associated with each
case can be included on the next line or on the same line. In the latter
case, we must use the keyword then.
The default case is handled in the else clause. The
generation of the hint in our example program could have been written as
follows:
case h
when 1..5 then puts ("TOO HOT!")
when 6..10 then puts ("CALIENTE")
when 11..15 then puts ("TEMPLADO")
else puts ("FRIO")
endRuby offers two ways to generate ranges: .. and
.... The difference between one and the other is that the
first .. includes the final element of the range and
... excludes it. So 1..5 generates a range
from 1 to 5, both inclusive, but
1...5 generates a range that does not include the value
5.
Constants in Ruby are simply variables whose name starts with a capital letter. However, unlike other languages like Perl and Python, Ruby really treats those variables in a special way. Ruby allows you to reassign a value to a constant, but it will emit a warning when you try to do so.
There are a few more caveats regarding the use of constants in Ruby, but the most important is that they cannot be declared within methods or functions, but they can be declared within classes.
In our example, the number N that we must guess is named
with uppercase letters and therefore it will be a constant. You can
change its value, but a warning message will be displayed on the
screen.
Summary
- Supports
if ... [elsif] ...[else] ... - Supports ternary operator
(cond) ? value_True : Value_False - Does not support booleans but defines values
true and false - Does not support
switch:case variable ... when pattern .. else - Supports constants. Only declare a variable in uppercase