Ruby Methods
Tags: ruby, tutorial, beginners
Published: 2020-05-12 20:54:50

In previous lessons, we discussed variables and logic in Ruby. Today we're going to discuss methods, what they are, and how to define them among other things.

<h1>What are Methods in Ruby?</h1>
Methods are simply instructions for your program to follow when the method is called. If you compare the variables we learned about before to 'nouns', you could make the analogy methods are 'verbs'.

The power of methods is only limited by one thing: the creator's imagination...ok there are *some* technical limits as well, but you get me. They are powerful tools that allow you to customize and optimize your program to whatever means you seem fit. 

Probably the largest benefit to methods is the ability to store the action for later use. Unlike the types of variables and conditionals we used earlier, which run each time we run our program, methods will only run when they are called somewhere inside the program. 

An example of a method could be our "Sam Sees Ghost" example from an earlier lesson. Turning this into a method is as easy as wrapping our code in the `def` (short for define) & `end` keywords like so:

```ruby
def seeing_ghosts #Line 1 defines and names the method
    sam_tds = 0 
    sam_ints = 4 #Line 2 & 3 Define our variables relevant to the method. 
    puts sam_tds > sam_ints ? "Jets win!!" : (sam_ints >=4 ? "I'm seeing ghosts." : "Jets lose!!") 
#In Line 4 we define the behavior(s) we want our program to make when this method is called
end #And finally, we close the method with the 'end' keyword.
```
It's important to note we have to define our variables *inside* the method. Method's have there own level of `Scope`, which we will get deeper into in a later lesson. For now, just remember to define any variable you will need inside the method.

Now our method won't run automatically, we have to call it somewhere else in our program. So let's add a call for our method right underneath it:

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

seeing_ghosts #=> I'm seeing ghosts.
#This is a call that will tell our program to run the 'seeing_ghosts' method
```

And we've successfully turned our code into a method!

<h1>Arguments</h1>
The above method is great and all, but it is written in a way that assumes Sam is the only one who sees ghosts! If we wanted to introduce ways to see if Dak Prescott or Big Ben see ghosts, we would have to write entirely different methods for each one. As a programmer, and especially a Rubyist, I'm too lazy for that - and so should you be! Enter arguments.

Arguments are a way to make our methods more dynamic and reusable. By adding in arguments and changing the hard-coded parts of our previous method, we can make it useful in a multitude of situations!

As an added bonus, arguments will also allow us to access variables *outside* of the method! For starters, let's see how our original `seeing_ghosts` method looks with arguments:

```ruby
sam_tds = 0
sam_ints = 4

def seeing_ghosts(tds, ints) #The '()' after the method name denotes this method takes the arguments 'sam_tds' & 'sam_ints'. 
    puts sam_tds > sam_ints ? "Jets win!!" : (sam_ints >=4 ? "I'm seeing ghosts." : "Jets lose!!")
end

seeing_ghosts(sam_tds, sam_ints) #=> I'm seeing ghosts.
```

Just like that, we have a method with 1/3 less fat on it and we will be able to use those variables elsewhere in our code without redefining them as well!

But this method still discriminates against Sam, and I don't write code to only make Bills and Giants fans happy. So we will begin making this method a bit less Sam-specific (and use more conventional conditional logic):

```ruby
def seeing_ghosts(tds, ints)
  if tds> ints
    puts "We win!!"
  elsif ints >=4 
    puts "I'm seeing ghosts."
  else
    puts "We lose!!"
  end
end
```

**Note** You can name your arguments anything, but try to keep a good sense of abstraction to make them easier to read. Here I decided `tds` & `ints` were specific enough so we could all understand what we are trying to do in the method.


This method will allow us the flexibility to enter either the number of `tds`/`ints` manually or place any defined variables from our code:

```ruby
sam_tds = 0
sam_ints = 4

seeing_ghosts(sam_tds, sam_ints)
#=> I'm seeing ghosts.
```

Will work the same as:

```ruby
seeing_ghosts(0, 4)
#=> I'm seeing ghosts.
```

<h1>Default Arguments</h1>
This method is *pretty* close to what we had in the last lesson, but we did have to cut out the team name to make it fit any QB. How can we call methods powerful if it just forces us to stupify our code and make it more generic?

The simple answer: it doesn't. We can add another argument called `team`, specify the team the QB plays for, and then use our old friend string interpolation! So let's do it!

```ruby
def seeing_ghosts(tds, ints, team)
  if tds> ints
    puts "#{team} win!!"
  elsif ints >=4 
    puts "I'm seeing ghosts."
  else
    puts "#{team} lose!!"
  end
end

seeing_ghosts(7, 0, "Eagles")
#=> Eagles win!!
```
That's great and all, but as a Jets fan, I spend most of my time talking about and caring about the Jets. I don't want to type the team name every time if I don't have to. People should know I'm talking about the Jets by default, right?

Right!

You can set a default value that will automatically be passed if you choose not to specify a value for that argument! So lets set `team` to equal "Jets" by default!:

```ruby
def seeing_ghosts(tds, ints, team = "Jets")
  if tds> ints
    puts "#{team} win!!"
  elsif ints >=4 
    puts "I'm seeing ghosts."
  else
    puts "#{team} lose!!"
  end
end

seeing_ghosts(2, 0)
#=> Jets win!!
```

There is no limit to the number of arguments you can assign a default value. We could add a `name` argument and set the default to `= "He"` for a generic QB quote like `"#{name} is seeing ghosts."` and a whole bunch more customizable options. 

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