Ruby Shorthands 101
Ruby “if” Statement Short Expression
In Ruby, the if
statement can be expressed in a single line in the case of a short expression. This single line would consist of an expression followed by the if
keyword and finally an expression that evaluates to either true
or false
.
Example
num = 6
if num % 2 == 0
puts “This number is even!”
end
Shorthand:
puts “This number is even!” if num % 2 == 0
Ruby Ternary Operator
In Ruby, a ternary operator is a more concise alternative to an if/else
. It consists of a conditional, followed by ?
and an expression to be evaluated if the conditional is true
, and then :
and an expression to evaluate if the conditional is false
.
tacos_eaten = 12
puts tacos_eaten >= 5 ? “Sir, you’ve had enough!” : “Keep eating tacos!”
The Case Statement
The if
/else
statement is powerful, but we can get bogged down in if
s and elsif
s if we have a lot of conditions to check. Thankfully, Ruby provides us with a concise alternative: the case
statement. The syntax looks like this:
Example
case language
when “JS”.
puts “Websites!”
when “Python”
puts “Science!”
when “Ruby”
puts “Web apps!”
else
puts “I don’t know!”
end
shorthand
case language
when “JS” then puts “Websites!”
when “Python” then puts “Science!”
when “Ruby” then puts “Web apps!”
else puts “I don’t know!”
end
Conditional Assignment
if we only want to assign a variable if it hasn’t already been assigned,For this, we can use the conditional assignment operator: ||=
. It’s made up of the or (||
) logical operator and the normal =
assignment operator.
favorite_book ||= “Cat’s Cradle”
Short-Circuit Evaluation
Recall that we have the boolean operators and(&&
) and or (||
) in Ruby. The &&
operator only returns true
when the expressions on both sides of the operator are true; ||
returns true
when one or the other or both of the expressions involved are true.
false && true
false || true
Up the Down Staircase
If we know the range of numbers we’d like to include, we can use .upto
and .downto
. This is a much more Rubyist solution than trying to use a for
loop that stops when a counter variable hits a certain value.
We might use .upto
to print out a specific range of values:
95.upto(100) { |num| print num, “ “ }
# Prints 95 96 97 98 99 100
and we can use .downto
to do the same thing with descending values.
Proc Syntax
Procs are easy to define! You just call Proc.new
and pass in the block you want to save. Here’s how we’d create a proc called cube
that cubes a number (raises it to the third power):
cube = Proc.new { |x| x ** 3 }
[1, 2, 3].collect!(&cube)
Why bother saving our blocks as procs? There are two main advantages:
- Procs are full-fledged objects, so they have all the powers and abilities of objects. (Blocks do not.)
- Unlike blocks, procs can be called over and over without rewriting them. This prevents you from having to retype the contents of your block every time you need to execute a particular bit of code.
The Ruby Lambda
Like procs, lambdas are objects. The similarities don’t stop there: with the exception of a bit of syntax and a few behavioral quirks, lambdas are identical to procs.
lambda { |param| block }
Lambdas are useful in the same situations in which you’d use a proc. We’ll cover the differences between lambdas and procs in the next exercise; in the meantime, let’s get a little practice in with the lambda
syntax.
First, a lambda checks the number of arguments passed to it, while a proc does not. This means that a lambda will throw an error if you pass it the wrong number of arguments, whereas a proc will ignore unexpected arguments and assign nil
to any that are missing.
Second, when a lambda returns, it passes control back to the calling method; when a proc returns, it does so immediately, without going back to the calling method.
first_half = lambda { |x,y| y<”M”}