If Statements in Ruby
Prehaps the most central concept to all of program. The classic if statement:
The basic if statement is nearly identical in Ruby:
It really only becomes slighty different when you get to the if…else if…else statements:
Now I apologize ahead of time, but it’s really not that different in Ruby. The only real difference is the keyword elsif instead of the fully spelled out else if like we’re used to:
Variable Assignments in If Statements
Here’s where PHP and Ruby start to diverge in the simple if statement. In PHP if we want to assign a variable while using a conditional, we cannot do something like this:
PHP will complain loudly. Instead we do thing like this:
We can assign variables inside of the condition. However, we cannot assign the result of a function to a variable.
Ruby says, why not?
result = if 1 == 1
puts 'facts'
return false
end
=> 'facts'
=> result
=> false
Guard Statements
Guard statements are a unique concept to Ruby - at least coming from a PHP background.
They’re actually used quite a bit as a way of controlling program flow in PHP:
In my PHP pseudo code example, we check to see if the current user is not authenticated - a.k.a. is a guest. If they’re not logged in, then we do not allow them to order delicious pancakes.
Instead, we throw them an unauthenciated page of some sort. Once they login, then they can think about ordering breakfast.
This is an example of a guard statement. The only difference that Ruby tacks on to this concept is that you can accomplish the same idea in one line:
user.create_order(params['pancakes_count']) if request.authenticated?
This way the user.create_order
isn’t called if the request.authenticated?
returns false.
Unless vs. !
In PHP we’re used to !
mean NOT or the opposite.
Here we only update the user->name
if the $name
variable is not null. It’s only one small character, but it essentially reverses the logic of the conditional. It’s such a small detail that it’s easily overlooked, and an overlooked !
in a conditional can be a huge pain in the rear.
Using !
in a conditional is very un-Ruby like. Instead of that tiny little character reversing the flow of the logic, Ruby has a reserved keyword for that. Let’s introduce our friend unless
:
unless name.nil?
user.update({
name: name
})
end
Ruby tries it’s darnest to read like human language. After years of !
it may take some time for this keyword to be intuitive but it will click. It literally reads unless the name is nil then update the user’s name.
Let’s combine Ruby Guard statements with unless
to refactor this code into a one liner:
user.update({ name: name }) unless name.nil?
Common operations like checking for presence of variables is a breeze thanks to clever conditional placement.
What the heck is ? doing in method names?
You may have raised an eyebrow to a question mark character in my method example name.nil?
. This is another weird concept that’s in Ruby but not in PHP. You are allowed to place certain punction marks in method names.
It’s very Ruby-list to end a method with a ?
if that method returns a boolean value.
For example .nil?
is a built in method in every Ruby Object. It returns true or false if the current Object is actually Nil
.
In PHP, we have a pseudo standard of naming methods that return a boolean by prefixing them with is
. You’ll come across some methods in PHP classes like isAdmin()
or isFulfilled
, etc.
Extra Ruby fun, yes you can use !’s in method names!
As you venture out into real Ruby code, you’ll occasionally see methods that end with a !
. This simply means that the operatio will affect the original variable.
For example .map
is a common function that maps a functio over an array. Each item in the array is transformed by the function passed to .map
. When the array is fully iterated over, the result is stored in a result variable:
numbers = [1, 2, 3]
# this is the classic multiplier example to show how .map works:
result = numbers.map do |number|
number * 2
end
puts result
puts numbers
=> [2, 4, 6]
=> [1, 2, 3]
The result
is the result of the mapping. However, the original numbers
array emerges unscathed.
Now let’s add a .map!
to see the difference:
numbers = [1, 2, 3]
# this is the classic multiplier example to show how .map works:
result = numbers.map! do |number|
number * 2
end
puts result
puts numbers
=> [2, 4, 6]
=> [2, 4, 6]
.map!
totally applied the mapping to the original variable a.k.a. numbers
. Now your original list is gone and replaced by the mapping. You can see how this is useful, but also potentially dangerous. I’ll let you use your best judgement on how to wield this power.