Home Accessibility Courses Diary The Mouth Forum Resources Site Map About Us Contact
 
For 2023 (and 2024 ...) - we are now fully retired from IT training.
We have made many, many friends over 25 years of teaching about Python, Tcl, Perl, PHP, Lua, Java, C and C++ - and MySQL, Linux and Solaris/SunOS too. Our training notes are now very much out of date, but due to upward compatability most of our examples remain operational and even relevant ad you are welcome to make us if them "as seen" and at your own risk.

Lisa and I (Graham) now live in what was our training centre in Melksham - happy to meet with former delegates here - but do check ahead before coming round. We are far from inactive - rather, enjoying the times that we are retired but still healthy enough in mind and body to be active!

I am also active in many other area and still look after a lot of web sites - you can find an index ((here))
Conditionals, loops, and iterators in Ruby

Ruby supports the following conditionals:
 
 if - perform a block if true
 unless - perform a block if false
 case - perform options when a condition is true.

All three also accept an else block, and if supports an elsif block. If and unless both work as code modifiers (i.e. the statement can be written the other way around) and in all three cases code execution continues beyond the statement once it has been completed.

Here's an example of the structure of each:

print "Please enter an integer "
value = gets.chomp.to_i
print "Testing the number #{value}\n"


# normal if, with elif and else
if value > 5
        puts "Value is greater than 5"
elsif value > 2
        puts "Greater that 2 but less than 5"
else
        puts "Less than or equal to 2"
end


# an if that's a code modifier
puts "That's very big" if value > 10


# An unless and else
unless value > 5
        puts "Value is not greater than 5"
else
        puts "That's greater that 5"
end


# an unless that's a code modifier
puts "That's not very big" unless value > 10


# Case - any one condition (or 'else' if none
# of the conditions matches exactly)
case value
when 1,21,31
        suffix = "st"
when 2,22
        suffix = "nd"
when 3,23
        suffix = "rd"
else
        suffix = "th"
end

puts "It is the #{value}#{suffix} of the month"

Let's run some tests on that:

earth-wind-and-fire:~/ruby/r104 grahamellis$ ruby condi.rb
Please enter an integer 2
Testing the number 2
Less than or equal to 2
Value is not greater than 5
That's not very big
It is the 2nd of the month
earth-wind-and-fire:~/ruby/r104 grahamellis$ ruby condi.rb
Please enter an integer 14
Testing the number 14
Value is greater than 5
That's very big
That's greater that 5
It is the 14th of the month
earth-wind-and-fire:~/ruby/r104 grahamellis$ ruby condi.rb
Please enter an integer 7
Testing the number 7
Value is greater than 5
That's greater that 5
That's not very big
It is the 7th of the month
earth-wind-and-fire:~/ruby/r104 grahamellis$

You'll note that my case takes a series of possible options on each when clause, and that it does NOT have a break at the end of each of the conditions, which you would expect to find in most switch type statements - case has been very neatly implemented in Ruby!

LOOPS IN RUBY

Ruby provides you with the basic while and unless loops and iterators. Let's get an example of while and unless out of the way first before looking at the much more useful, high level and efficient operators.

A "while" loop defines that a statement or block of code is to be rerun time and time again while a condition remains true, and then execution is to continue after the statement or block. An "until" loop says that the block is to be performed until the condition goes true (i.e. while it is false).

Just like the "if" and "unless", "while" and "until" are written with an 'end' key-worded block, or as modified after a piece of code.

Sample code:

# Examples of Ruby loop structures

top = 4

# A while loop, counting up
now = 0
while now < top
    puts "while #{now} .. #{top}"
    now += 1
    end


# While written in one line
now = 0
print "#{now+=1} " while now < top
print "\n"


# An until loop
now = 0
until now > top
    puts "until #{now} .. #{top}"
    now += 1
    end


# Until written in one line
needed = 1
teams = 19
needed *= 2 until needed >= teams
print "You have #{teams} teams so ideally ",
        "need #{needed}.\n"

When that code is run, here are the results:

earth-wind-and-fire:~/ruby/r104 grahamellis$ ruby loopy.rb
while 0 .. 4
while 1 .. 4
while 2 .. 4
while 3 .. 4
1 2 3 4
until 0 .. 4
until 1 .. 4
until 2 .. 4
until 3 .. 4
until 4 .. 4
You have 19 teams so ideally need 32.
earth-wind-and-fire:~/ruby/r104 grahamellis$

ITERATORS

The method "each" when run on what we call a collection object will cause a block of code to be run on each of the elements of the collection object in turn. Yes, that's rather different to many other languages (though it does parallel foreach in PHP and for in Python).

You can write a loop that looks reasonably conventional to step up through a series of numbers - example coming up - but in addition you can write far clearer and more elegant loops to process all the members of a collection in turn, without having to refer to them by their position number all the time.


# Some for loops that might almost look familiar

# From 1 to 20
for k in 1..20
   print k," "
end
print "\n"


# From 1, stopping short of 20
for k in 1...20
   print k," "
end
print "\n"


# An iterator object revealed!
(5..15).each do |k|
   print k," "
end
print "\n"

Here's how it runs.

earth-wind-and-fire:~/ruby/r104 grahamellis$ ruby ddd.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
5 6 7 8 9 10 11 12 13 14 15
earth-wind-and-fire:~/ruby/r104 grahamellis$

Note those .. and ... operators, and the subtle difference - in the first case, you're returned an iterator that runs up from the first to the last number, but in the second case the iterator stops one short of the last number. This means that is you have (say) a collection of 10 items numbered from 0 to 9 - which is quite common - you'll be able to write 0...10 or even 0...coll.length and not have to worry about a -1 correction.

COMPARATORS IN RUBY

There are multiple comparators in Ruby, and they're all adjusted dynamically to suit the objects on which they're being run. The three you'll need to remember will be:
  
  == - regular equality test, true if objects have same value
  eql? - method true if objects have same value AND TYPE
  equal? - true if both object have the same ID (i.e. same obj)

A further test - === - is used by the case statement and can be independently overridden if you wish later on, and the <=> operator returns -1, 0 or +1 when comparing two objects, for less than, equal or greater than.

Here's a demonstration of the comparisons, showing some differences:

first = 10
second = 10.0

puts "Comparing #{first} with #{second}"
puts "two = signs" if first==second
puts "three = signs" if first===second
puts "eql? method" if first.eql?second
puts "equal? method" if first.equal?second

second=first
puts "Comparing #{first} with #{second}"
puts "two = signs" if first==second
puts "three = signs" if first===second
puts "eql? method" if first.eql?second
puts "equal? method" if first.equal?second

And here's how it runs:

earth-wind-and-fire:~/ruby/r104 grahamellis$ ruby ctors.rb
Comparing 10 with 10.0
two = signs
three = signs
Comparing 10 with 10
two = signs
three = signs
eql? method
equal? method
earth-wind-and-fire:~/ruby/r104 grahamellis$

Ruby also supports lazy operators - "and" means "and if true", and "or" means "and if false". The ? : operator from other languages is supported too.

stock = 0..5
for number in stock
        num = number

# "and" is lazy. If the first part is false, then
# the whole expression will be false - so ruby doesn't
# bother to go on to the second test nor the assignment
# it includes.

        num == 0 and num = "none"

# "? ... :" is an "if true x else y" type operator.

        word = num == 1 ? "is" : "are"

        print "There #{word} #{num} in stock\n"

end

We run that and get:

earth-wind-and-fire:~/ruby/r104 grahamellis$ ruby lazyops.rb
lazyops.rb:12: warning: found = in conditional, should be ==
There are none in stock
There is 1 in stock
There are 2 in stock
There are 3 in stock
There are 4 in stock
There are 5 in stock
earth-wind-and-fire:~/ruby/r104 grahamellis$

so perhaps the lazy and / or aren't such a good idea!



See also Ruby course - UK, Ireland, Europe

Please note that articles in this section of our web site were current and correct to the best of our ability when published, but by the nature of our business may go out of date quite quickly. The quoting of a price, contract term or any other information in this area of our website is NOT an offer to supply now on those terms - please check back via our main web site

Related Material

Ruby - Control Structures
  [960] - ()
  [962] - ()
  [985] - ()
  [995] - ()
  [1163] - ()
  [1220] - ()
  [1582] - ()
  [1587] - ()
  [1696] - ()
  [1738] - ()
  [1870] - ()
  [1887] - ()
  [1891] - ()
  [1904] - ()
  [2287] - ()
  [2471] - ()
  [2619] - ()
  [2711] - ()
  [2892] - ()
  [2975] - ()
  [3156] - ()
  [3158] - ()
  [3159] - ()
  [3200] - ()
  [3253] - ()
  [3254] - ()
  [3397] - ()
  [3422] - ()
  [3619] - ()
  [3620] - ()
  [3769] - ()
  [4322] - ()
  [4323] - ()
  [4370] - ()
  [4402] - ()
  [4503] - ()
  [4504] - ()
  [4674] - ()

Ruby - Introduction
  [550] - ()
  [664] - ()
  [1027] - ()
  [1041] - ()
  [1302] - ()
  [1375] - ()
  [1887] - ()
  [2286] - ()
  [2287] - ()
  [2607] - ()
  [4369] - ()
  [4498] - ()

resource index - Ruby
Solutions centre home page

You'll find shorter technical items at The Horse's Mouth and delegate's questions answered at the Opentalk forum.

At Well House Consultants, we provide training courses on subjects such as Ruby, Lua, Perl, Python, Linux, C, C++, Tcl/Tk, Tomcat, PHP and MySQL. We're asked (and answer) many questions, and answers to those which are of general interest are published in this area of our site.

You can Add a comment or ranking to this page

© WELL HOUSE CONSULTANTS LTD., 2024: Well House Manor • 48 Spa Road • Melksham, Wiltshire • United Kingdom • SN12 7NY
PH: 01144 1225 708225 • FAX: 01144 1225 793803 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho

PAGE: http://www.wellho.net/solutions/ruby-con ... -ruby.html • PAGE BUILT: Wed Mar 28 07:47:11 2012 • BUILD SYSTEM: wizard