Thursday, February 3, 2011

Working with Nesting Logic in Ruby

So you want to talk about nesting logic? Ok, let's do it. We can talk about elsif too.

For a while, I didn't get why a piece of code such as:

puts "I don't need an end, dude"

Didn't need to be written as

puts "I don't need an end, dude"

While something like this:

fruit = "potato"
if fruit == "orange"
color = "orange"
puts "You have an orange."
elsif fruit == "apple"
color = "green"
puts "You have a green apple."
elsif fruit == "banana"
color = "yellow"
puts "You have a banana."
color = "unknown"
puts "You have something that I don't know what it is."

DOES need the end delimiter. (I didn't know this was called a delimiter. Is that what everyone calls it? It sounds more like something the Ghostbusters would use than a piece of code but ok)

But when I was finishing up Chapter 3 in Beginning Ruby, it made sense. You need the end to tell Ruby that the previous argument is over. It's DONE, Ruby. Let's start a new one! Am I thinking about this in the right way?

So far my learning has been something like I'm given a piece of the puzzle, by Beginning Ruby or a friend or a tutorial online and I don't fully get what the piece is for until I work a little further.

Also while I was working on stuff tonight I built a perpetual motion machine.

x = 1
while x = 1
puts x

Perpetual until you stop the task anyway!

Really looking forward to digging into Chapter 4 this weekend. It walks you through building a functional (though basic) Ruby program and I think some real practical experience will do me a world of good.


  1. Your perpetual motion machine has a very common bug you should try to keep your eye out for:

    x = 1 # assignment
    while x = 1 # assignment, you probably meant to use == for comparison
      puts x

    Also, check it:

    loop do
      puts "tick"

  2. As far as the end statement, some statements signify the beginning of a group of statement (if/unless/else/elsif/case/begin/loop/while/until/do/class/module/etc.) Since the number of statements is not known in advance, you need to tell it where to stop.

    Many programming languages use curly braces to denote this group of statements, and they are always paired. In Ruby a more succinct form is preferred where common grouping commands simply imply the start of a group of statements and only the end is required. Some of Ruby's best features are about reducing tedium in code, and this is one example.

    if (123) {

    if 123
      puts '123'

    You will very quickly memorize things that require an end statement. It is particularly easy if you remember that everything that groups a set of statements, needs an end.

    Two obvious exceptions to this are if/unless when they are appended to a statement. Because they can only append to a single statement, no end is needed to signify a limit to the group.

    statement if true # no end needed

  3. @Eli Yeah, the use of the end statement threw me for a while. Beginning Ruby kind of just says "Here, use this code. Here's what it does," without explaining what the individual parts of the code do.

    Although it's fine, because that explanation presents itself naturally anyway, I still get tripped up on these things. So it's best to just continue on and trust that I'll understand it in the future.