Methods

Back

Learning Goals

  • Explain the purpose of methods
  • Use built-in methods on appropriate objects based on data type
  • Define and call methods in Ruby
  • Use and explain the flow of data with arguments and parameters
  • Describe the purpose of a return value

Vocabulary

  • method
  • define
  • execute or call
  • return
  • parameter
  • argument

Methods

A Method is a package of instructions. Once a method is defined, it can be used as many times as needed. Ruby provides many built-in methods that developers can use.

Defining Our Own Methods

There are many methods that are built into the Ruby language. Those are great and you will use them regularly as a developer (and you’ll explore them later today!). There will also be times when you need to write your own method to solve a unique problem in the application you are building or maintaining.

Syntax for Defining a Method

To define our own method, we’ll use the following guidelines:

  • The def and end keywords act like bookends for the code block.
  • Following the keyword def, we assign our method a name. It’s best if the name describes what the method does.
  • The code block is indented and contains all of the “instructions” for what the method should do when it is called.
  • The value on the last line of the code block is the data that the method will return when it is called.

In the method below, the code block has only one line, but it’s important to note that there could be many lines of code within the code block, describing the steps that a method should follow. You can even include other things we’ve learned like conditionals and built-in methods within your code block.

# method definition
def greet_a_texan
  "Howdy, partner!"
end

After defining a method, nothing will appear to happen. The interpreter that reads the Ruby code will read it, and be aware of that set of instructions, but it won’t carry out those instructions until it is explicitly told to do so.

Syntax for Calling a Method

To instruct the interpreter to carry out the instructions in a method, the developer must write code to call or execute that method. Simply writing the name of the method, greet_a_texan in this example, calls or executes the method. When we call this method by writing the name of the method, it triggers the “instructions” held within the code block of that method. Now, this method by itself only returns the string “Howdy, partner!” - we still need to use a puts command to see that return value in the console.

# method call
greet_a_texan

Naming Conventions

Since methods provide action to a program, they should be named accordingly; it’s best practice to start them with a verb. Like variables, Ruby methods should use snake_case when they involve more than one word and should be written carefully to describe their role specifically without being overly verbose.

Examples of method names that follow best practices:

  • get_user_input
  • display_followers
  • add_two_numbers
  • find_longest_name

In the example above, the developer chose the method name of greet_a_texan. Method names should usually include verbs, since methods do something. The definition just tells the program that it’s a set of directions ready to be followed; the method call is what makes the code in the method execute, or follow the packaged directions. You can call a method as many times as you want, once it’s been defined!

A Method Metaphor

Often, we want to use a method to perform an action on or with a piece of data. Think back to those built-in methods. We didn’t simply call the odd? method by itself. We called it on an Integer object and it returned a Boolean value. We can do the same thing with the methods we define. Think of your method like a machine with inputs and outputs.

If this were a cookie machine, for example, the machine would take in all of the raw ingredients (eggs, flour, sugar, etc.) and perform some steps to make the cookies:

  1. Mix ingredients to make dough
  2. Place dough balls on a baking sheet
  3. Bake at 350 degrees for 10 minutes
  4. Let cookies cool
  5. Serve the cookies on a plate

We can imagine that our cookie machine would do all of those steps and then give us back freshly baked, warm cookies!

Let’s expand this example to any kind of machine. We give the machine the raw materials, it does something with those materials, and then returns the final product. This is very similar to what we are doing with our own methods. We give the method some piece of data or information (or even multiple pieces of information) and then the method does something with that information and spits out a return value.

Think About It

Look at the method call below and make a guess about how this might be different from the previous method example.

  greet_a_texan("Kaitlyn")
  # => "Howdy, Kaitlyn!"


Without possibly having all the information about Ruby syntax, you probably made some connection as to what might be happening with the previous code snippet. The greet_a_texan method was called, but this time, we were able to dynamically change the name of the person we were greeting!

Arguments & Parameters

Arguments are the technical term for the inputs to a method such as the String that was provided in the parenthesis after the method name in the previous example. As developers, we have the control to name the parameters, or placeholders, for the data that will be passed in. Those names should follow variable name conventions and be concise, yet descriptive. The number of arguments passed in should match the number of parameters declared.

# name is a parameter
def greet_a_texan(name)
  "Howdy, #{name}!"
end

# "Kaitlyn" is the argument for this method call
puts greet_a_texan("Kaitlyn")
# => "Howdy, Kaitlyn!"

# "Brian" is the argument for this method call
puts greet_a_texan("Brian")
# => "Howdy, Brian!"

Note: You’ll notice that we are using the puts command in front of the method call this time. This allows us to also see the return value of the greet_a_texan method printed to the console, but it is not necessary. The code greet_a_texan("Kaitlyn") by itself does return the string “Howdy, Kaitlyn!”, but if we want to see it printed in the console, we will need to use puts or print along with the method call.


Practice

  • Write a method named greet_an_animal. This method should declare one parameter, a String, and when called, should return a string with a greeting for the specific animal that was passed in as an argument.
  • Write a method named multiply. This method should declare two parameters, both Integers, and when called, should return the product of the two Integers. Call the method several times with different arguments and run the code to ensure it's working as expected.


Return Values

A return value is either:

  • Defined implicity: By default, the last line of code automatically becomes the return value of the method.
    OR
  • Defined explicitly: By using the return keyword, we can also specify the return value of the method.

In the add example below, the return value is an Integer or Float, based on what values were passed in as arguments. If 2 and 3 are passed in, the return value is 5. This is called an implicit return. Ruby automatically returns the value of the last expression in a method if no return is present. For this reason, if we want to return the value of the last expression in a method, we usually do not use the return keyword, as it is considered redundant and unnecessary.

def add(num1, num2)
  num1 + num2
end

add(2, 3)
# => 5 (return value is 5 since that's the sum of 2+3, and on the last line of the method)

In the subtract example below, the return value will be whatever is stored in the difference variable. If 10 and 7 are passed in as arguments, the return value is 3 because the last line of the method uses the return keyword to return the difference variable. This is called an explicit return.

def subtract(bigger, smaller)
  difference = bigger - smaller
  return difference
end

subtract(10, 7)
#  => 3 (return value is 3 since it is stored in the difference variable, and the last line of the method uses the return keyword)

Best Practices

Typically, we do not include an explicit return unless it is absolutely necessary. Since ruby methods automatically return the value of the last line, it's common practice to use implicit returns like in the first example above.


Be Careful with puts Inside of Your Method

In the say_goodbye example below, notice we included the puts command in the last line of the method instead of returning a data point. The return value is nil because the last line of code is puts "See you later", and puts is a built-in command with a return value of nil. This is generally not a best practice, because the method doesn’t return any usable data.

def say_goodbye
  puts "See you later!"
end

say_goodbye
# "See you later!" will be printed to the console
# The return value is nil because puts is on the last line of the method and the return value of the puts method is always nil

Key Point: Up until now, we’ve use the puts and print commands to see values printed to the console. Be careful not to confuse what you see in the console with the return value of the method – these are two different things. We use puts and print to see data in the console, but what we see in the console is not always the return values.


Storing a Return Value

The examples we’ve looked at so far call the method and execute the code within the method, but the return values go nowhere/can never be used in the program again. Many times, we’ll store the return value of a method in another variable, as modeled below:

def add(num1, num2)
  num1 + num2
end

sum1 = add(2, 3)
sum2 = add(7, 9)

puts sum1
puts sum2


Practice

  • Write a method named get_age. This method should declare one parameter, an Integer, representing a birth year.
  • When called, the method should calculate the person's approximate age. Let's not worry about birth month or day. 😉
  • The method should return an Integer representing the person's age.
  • Call the method several times with different arguments and store the return values in variables.
  • Print a sentence that says, "You have lived ___ years of life!" with each variable interpolated into the String.


Key Points Summary

  • A method is a packaged set of directions. If the method is never called, it will never run. And a method can be called many times, if needed!
  • The number of arguments in a method call must match the number of parameters in the method definition.
  • Method names should start with a verb and use snake_case.
  • With an implicit return, the value on the last line of the code block is the data that will be returned when a method is called.
  • With an explicit return, the value after the return keyword is the data that will be returned when a method is called.


Self-Teach

Part of what you’ll experience at Turing is learning a technical topic on your own. Practicing this skill at Turing will get you prepared for the job where you will do this often.

Take time between now and your next session to self-teach the following section.

Warm-Up for Built-In Methods

Exploration: PART 1

Fork, then run the code in this replit and observe the output.

Think: How did each line of code, produce each respective line of output? Which parts make sense, and which are confusing?


Methods

A Method is a package of instructions. Once a method is defined, it can be used as many times as needed. Ruby provides many built-in methods that developers can use.

The code snippet that follows was part of the previous Exploration activity:

p 14.odd? 

To describe the code snippet in English, one could say, “the odd question mark method is being called on the Integer 14.” Since 14 is not odd, false will be the return value. The p command prints that return value of false to the console.

In this particular example, the utility of the odd? method is to determine if an Integer is odd, or not. It answers the question with a Boolean (true or false). The benefit of having this method built into Ruby is if a developer needs to check if a number is odd or not, they only have to type .odd? anywhere they need to check. If they didn’t have a pre-packaged method, they’d have to write several lines of code involving logic, every time they want to check if an integer is odd. Reusability is what makes methods so powerful.


Exploration: PART 2

In the same replit from the first exploration, comment out the code from Part 1, and uncomment the code under Part 2.

  • Run the code.
  • Think: What is different about this from the first set of method calls? How did each line of code, produce each respective line of output? Which parts make sense, and which are confusing?


The following code snippet demonstrates that a method can be called on a variable assigned to data:

new_string = "Hello World"
p new_string.upcase

To describe the code snippet in English, one could say, “the first line declares a variable called new_string and the second line calls the upcase method on the new_string variable.” As a result, the method will return a String object where any letter character in the original String stored in new_string will now be capitalized. The p command prints that return value of "HELLO WORLD" to the console. However, it’s important to note that the original data stored in new_string is not modified permanently.


Exploration: PART 3

In the same replit, comment out the code from Part 2, and uncomment the variable declarations and first method call under Part 3.

  • Run the code and read the error message carefully. Work to make sense of what the problem is.
  • Comment out that method call, and uncomment the next one. Run the code and read the error message carefully. Work to make sense of what the problem is.
  • Repeat the previous step until you've run the code for each method call.
  • Modify the existing code so that it runs without errors.
  • Write down a 1-3 sentence explanation of your main takeaway from this exploration.


Key Points

  • A method is a package of instructions that once defined, can be reused as many times as needed.
  • A method can be called on a variable that holds data.
  • Ruby provides built-in methods for each data type. Not every method will work on every type of data.


Check For Understanding

  • Complete the tasks in this repository.
  • Add a link to your respository under a new section of your Mod 0 Gist called Methods.





Back