Ruby If, Unless, While and Until
A step by step tutorial on the ruby if, unless, while and until control structures.
Ruby offers conventional control structures that are found in most common programming languages like if
, else
and while
, however, Ruby also provides less common options like until
and unless
. These control structures may seem weird at first (“who talks like that?”), but they have their advantages.
If Statement
Let’s start with a basic if
statement. Here we have a Movie
class with several attributes and functionality to only update a movie’s title if the in_progress
attribute is true
; easy enough. If in_progress
is true, then the title
attribute can be assigned a new value.
class Movie
attr_accessor :in_progress
attr_reader :title, :length, :budget
def title=(new_title)
if @in_progress
@title = new_title
end
end
end
Now let’s imagine if the attribute was finalized
instead of in_progress
. It may be tempting to put a not
or !
in front of it and call it a day.
class Movie
attr_accessor :finalized
attr_reader :title, :length, :budget
def title=(new_title)
if not @finalized
@title = new_title
end
end
end
This if statement is valid but is a little more verbose than it has to be. An alternative (and slightly more concise) way would be to use unless
.
class Movie
attr_accessor :finalized
attr_reader :title, :length, :budget
def title=(new_title)
unless @finalized
@title = new_title
end
end
end
Using unless
, the body of the statement (@title = new_title
) is only executed if the condition (@finalized
) is false
. Using unless
comes with a couple of benefits:
- It’s slightly shorter that using
if not
orif !
- It may become a little easier to read and understand once you get used to it
The second point is important. Reading an unless
statement may seem weird at first (when I first encountered it in a production app I had to read it as “if not” until I got used to it). But after a while it becomes less awkward and just another way to do a negative, or backwards, if statement.
There’s no “right” way to do it; it’s just a preference. The difference between an if not
and unless
is like saying:
- “It is
not true
that an apple is an orange” - “An apple is not an orange”
While and Until
Similar to unless
is the negative version of if
, until
is the negative version of while
A while
loop will keep looping while the condition (! download.is_finished?
) is true
. In this example, the condition reads “while not download is finished (execute the code block)”.
while !download.is_finished?
spinner.keep_spinning
end
An until
loop will keep looping until the condition (download.is_finished?
) is true
. In this example, the condition reads “until download is finished (execute the code block)”.
until download.is_finished?
spinner.keep_spinning
end
Again, it’s a matter of preference; but using until
became clearer once I understood the difference and became used to it.
We can also make these examples a little more concise and readable. Notice how the code block of the statements are only one line? Because it’s only one one line and is pretty short, we can condense the statements to just a single line.
spinner.keep_spinning while !download.is_finished?
spinner.keep_spinning until download.is_finished?
Just as before, it’s a matter of preference, but to me using until
is clearer and reads a little better.
That’s part of the reason I really like writing code in Ruby, there are multiple ways to do the same thing. The language provides tools you need to express yourself and does its best to stay out of your way. Does not if
make more sense to you or does writing unless
statements feel more natural? Either way is fine because Ruby provides both options! Same thing with while
and unless
.