Common Ruby Operators and Conditional Logic
Tags: ruby, tutorial, beginners
Published: 2020-05-08 18:38:43

This week I'm going to be covering common Ruby Operators (specifically the Comparison, common Boolean, and Ternary Operators) and an Introduction into Conditional Logic in Ruby as well.  

<h1>Booleans in Ruby</h1>
Firstly, let us get an idea of what a boolean is in Ruby. A boolean in Ruby is simply something that refers to a value of `true` or `false`. Unlike some other programming languages, Boolean is not its own class in Ruby. Instead Ruby has the [TrueClass](https://ruby-doc.org/core-2.5.0/TrueClass.html) and the [FalseClass](https://ruby-doc.org/core-2.5.0/FalseClass.html) which for this lesson should be an adequate explanation. Read the supplementary material linked for more info. 

<h1>The Common Ruby Operators</h1>
<strong>== aka The Comparison Operator:</strong> In the previous lesson we learned the `=` operator is used to declare a variable to a value. Ruby also boasts an operator `==` which is used to compare values and return `true` if both are equal.
Example:
```ruby
1==1 #=> true 
```
Whereas
```ruby
 1==2 #=> false
```
<strong>"!" aka The "Single-Bang" Operator</strong> `!` stands for "NOT". It's mainly used to manipulate something that is `true` into something that is `false` and vice versa.
```ruby
puts 2 #=> true
puts !2 #=> false
```

<strong>"&&" aka The "AND" operator</strong> The `&&` operator is used to tie 2 or more conditionals together. All values have to be true to be read as `true`.

```ruby
true && true #=> true
true && false #=> false
```
<strong>"||" aka The "OR" Operator</strong> Like the `&&` Operator the `||` Operator is also used to tie 2 or more conditionals together. The difference is only 1 of the conditionals has to be true to read as `true`. 
```ruby
true || true #=> true
true || false #=> true
```

<h1>"if", "elsif", and "else" in Ruby</h1>
`if`, `elsif`, and `else` all basically do the same thing: they tell the program to evaluate the proceeding conditional and if true to follow specific instructions. The most significant difference is where they are in an `if\else` statement. The following is the basic construct of an `if\else` statement in Ruby:
```ruby
if condition_is_true
  instruction1
elsif condition_above_is_false_check_this_and_if_true
  instruction2
else
  instruction3
end
```
Notice `else` has no conditional? In most cases `else` is meant to capture all other circumstances not caught by the preceding conditions and you can ignore specifics and just put instructions.

Also, note `elsif` is spelled funny. This is a rare moment where I feel Ruby tried *too hard* to simplify things for devs, as this is just silly grammar. 

Lastly, make sure to close out your conditionals with `end`.

And now, we can proceed to this week's example...

<h1>Sam Sees Ghosts</h1>
New York Jets Quarterback Sam Darnold is unfortunately judged far too harshly based on his "I'm seeing ghosts," game vs. New England. Outside of that 2 game stretch vs. NE and Jacksonville, he actually was really good!

But Sam did confess to seeing ghosts, and as such we as programmers have to acknowledge this truth in our code somehow. First, we can start by defining Sam's interceptions and touchdowns against NE.

```ruby
sam_ints = 4
sam_tds = 0
```
It was a terrible game.

Next, we will put our first `if` statement:

```ruby
if sam_tds > sam_ints
  puts "Jets win!!"
end
```
Obviously, this will output nothing in our console as `sam_tds` are less than `sam_ints`. So we need a condition that will output something when Sam has more INT's than TD's:

```ruby
if sam_tds > sam_ints
  puts "Jets win!!"
else 
  puts "Jets lose!!"
end

# Will return "Jets lose!!" in the console.
```
Great, so we have a condition to display in our console, but just losing is not quite the same as seeing ghosts, is it? Let's modify our logic and add a third conditional in there so Sam will let us know when he's seeing ghosts.
```ruby
if sam_tds > sam_ints
  puts "Jets win!!"
elsif sam_ints >= sam_tds
  puts "Jets lose!!"
else sam_ints >= 4
  puts "I'm seeing ghosts!"
end

# Will return "Jets lose!!" in the console.
```
Ok, what happened? Sam does have 4 or more int's so why wasn't that displayed? In Conditional Logic, the first conditional that processes as "true" will be the output. Since we cover all possible outcomes in our first two conditions, that is what will be read. For this reason, your more specific conditions should be higher up the logical ladder.

```ruby
if sam_ints >= 4 
    puts "I'm seeing ghosts."
elsif sam_ints < sam_tds
    puts "Jets win!!"
else sam_ints >= sam_tds
    puts "Jets lose!!"
end

# Will return "I'm seeing ghosts." in the console.
```

With this, Sam can now see ghosts. However, what if Sam has 4 INT's, but 7 TD's? It's likely the Jets won that game, but Sam is still seeing ghosts. How do we help Sam bust these ghosts? We could just switch the `if` and `elsif` conditionals and instructions, and that's totally fine!  Instead, we're going to use the "&&" to add an extra condition so our ghosts don't ruin Sam's gutsy performance.

```ruby
sam_ints = 4
sam_tds = 7

if sam_ints >= 4 && sam_ints >= sam_tds
    puts "I'm seeing ghosts."
elsif sam_ints < sam_tds
    puts "Jets win!!"
else sam_ints >= sam_tds
    puts "Jets lose!!"
end

# Will return "Jets win!!" in the console.
```
This gives us a much better grip over the flow control of when Sam sees ghosts.

<h1>The Ternary Operator</h1>
A convenient little operator for some simple Conditional Logic, the Ternary operator allows us to assign one value if a condition is true and another if a condition is false.

We write the Ternary Operator in this pattern:

`conditional ? action_if_true : action_if_false`

So the statement
```ruby
puts sam_ints >= sam_tds ? "I'm seeing ghosts." : "I'm not seeing ghosts."
```

Will produce the same result as the `if/else` statement:
```ruby
if sam_ints >= sam_tds
   puts "I'm seeing ghosts."
else
   puts "I'm not seeing ghosts."
end
```
Nice! The Ternary Operator allowed us to write shorter, more condensed code. But we had 3 possible outcomes in our example. Can we write code using the Ternary Operator that captures more than 2 values?

<h1>Bonus Ternary Lesson!</h1>
It's possible to manipulate your code to use the Ternary Operator for more than 2 expressions. This isn't very advisable in a pro setting, as it can get messy quickly and very difficult for other programmers to read. BUT in a code challenge setting combining what might take 6 lines into 1 line can feel like a major win in itself!. 

```ruby
puts sam_tds > sam_ints ? "Jets win!!" : (sam_ints >=4 ? "I'm seeing ghosts." : "Jets lose!!")
```

And voila! With the code above we can do everything our completed `if/else` statement can do in 1 line.

<h1>Conditionals Lab</h1>
When you're finished reviewing this lesson, head over to the [Ruby Conditionals Lab](https://github.com/BMWeygant/ruby-tutorial-conditionals-lab), and complete all the tasks given. Have fun and good luck!