Defining and Calling Methods in Ruby
Methods are the building blocks of Ruby programs. They let you group related code together, give it a name, and call it whenever you need it. Instead of writing the same code over and over, you define it once in a method and reuse it.
You’ll learn how to define methods, pass arguments, return values, and use the various Ruby method conventions.
Before you begin
Methods are one of the simplest ways to make Ruby code easier to read. They let you turn repeated steps into a single named action, which means the rest of the program can talk about what the code does instead of listing every instruction every time. That becomes especially helpful once a script grows past a few lines.
Another benefit is that methods create natural boundaries. One method can gather data, another can transform it, and another can print or return the result. When those boundaries stay clear, your code is easier to test and easier to change later.
tl;dr
Use methods to name repeated logic, accept inputs through parameters, and return results in a predictable way. Keep each method focused on one job, use descriptive names, and reach for default, keyword, or variable-length arguments when the call site needs more flexibility.
What is a Method?
A method is a named block of code that performs a specific task. Think of it as a reusable recipe: you define the instructions once, then “cook” (call) the method whenever you need the result.
Methods help you:
- Avoid repeating code
- Organize your program into logical pieces
- Make your code easier to read and maintain
- Break complex problems into smaller, manageable parts
When a method grows too large, that is usually a sign that it is trying to do too many jobs at once. Breaking the work into smaller methods often makes the code easier to test and easier to reuse elsewhere in the program.
defining a basic method
In Ruby, you define a method using the def keyword, followed by the method name, and end to close the definition:
def greet
puts "Hello, World!"
end
To run this method, you call it by name:
The def keyword opens a method definition, and end closes it. Inside the body, puts prints a message to standard output. To actually run this code, you call the method by its name. Ruby looks up the method definition and executes the body. The parentheses after the method name are optional when there are no arguments, so both greet() and greet work the same way.
greet
# Output: Hello, World!
This is the simplest form of a method—it takes no arguments and returns nothing useful (implicitly returns nil).
Methods with Parameters
Most useful methods accept input in the form of parameters. Parameters are variables that receive values when you call the method:
The greet method works but is limited because it always prints the same message. To make a method reusable across different inputs, you add parameters. A parameter is a variable name listed between the parentheses in the method definition. When you call the method, the argument you pass gets assigned to that parameter. This is how you make a single method work for Alice, Bob, or any name the caller supplies.
def greet_person(name)
puts "Hello, #{name}!"
end
greet_person("Alice")
# Output: Hello, Alice!
greet_person("Bob")
# Output: Hello, Bob!
The name parameter is a placeholder that gets replaced with the actual value (“Alice” or “Bob”) when the method runs.
default parameter values
You can provide default values for parameters. These are used when no argument is passed:
Sometimes you want a method to work even when the caller does not supply every argument. Default parameter values let you specify a fallback that Ruby uses when an argument is missing. The syntax name = "Stranger" assigns the string only when no argument is passed for that position. This pattern appears frequently in library code where sensible defaults reduce the amount of configuration the caller has to provide.
def greet_person(name = "Stranger")
puts "Hello, #{name}!"
end
greet_person
# Output: Hello, Stranger!
greet_person("Charlie")
# Output: Hello, Charlie!
Default parameters make methods more flexible—callers can provide custom values or skip arguments entirely.
returning values from methods
Ruby methods can return values using the return keyword, or implicitly return the last evaluated expression:
Methods that only print to the screen are limited because the caller cannot capture the result. The return keyword explicitly sends a value back to the caller. When Ruby executes return a + b, it computes the sum and exits the method immediately, handing that value to wherever the method was called. The result = add(3, 5) assignment stores the returned value in a local variable.
def add(a, b)
return a + b
end
result = add(3, 5)
puts result
# Output: 8
You can also omit return—Ruby automatically returns the last expression:
Ruby methods do not require an explicit return statement. If you omit return, the method automatically returns the value of the last expression evaluated in the body. The multiply method achieves the same effect as add but with one less keyword. Most Ruby developers prefer the implicit style and reserve explicit return for early exits, where you want to leave the method before reaching the last line.
def multiply(a, b)
a * b
end
result = multiply(4, 7)
puts result
# Output: 28
Multiple Parameters
Methods can accept any number of parameters:
Methods are not limited to one or two parameters. You can list as many as you need, separated by commas. The introduce method accepts three parameters and interpolates them into a sentence. Each parameter name should describe the value it expects, which makes the method signature self-documenting. When you call the method, Ruby matches arguments to parameters by position, so the first argument becomes name, the second becomes age, and the third becomes city.
def introduce(name, age, city)
puts "I am #{name}, #{age} years old, from #{city}."
end
introduce("Diana", 28, "London")
# Output: I am Diana, 28 years old, from London.
Variable-Length Arguments
Ruby supports methods that accept a variable number of arguments using the splat operator (*):
Fixed parameter lists work when you know exactly how many arguments to expect. When you need flexibility, the splat operator * collects any number of arguments into an array. Inside the method, numbers is a plain array that you can iterate, reduce, or pass to another method. This pattern is common in math helpers, logging methods, and any situation where the caller might supply a variable number of values.
def sum(*numbers)
total = 0
numbers.each { |n| total += n }
total
end
puts sum(1, 2)
# Output: 3
puts sum(1, 2, 3, 4, 5)
# Output: 15
puts sum()
# Output: 0
The *numbers collects all arguments into an array, letting you handle any number of inputs.
Keyword Arguments
Ruby also supports keyword arguments, which are more explicit and self-documenting:
Positional arguments are concise but can become confusing when a method takes more than two or three parameters. Keyword arguments solve this by making the caller name each argument explicitly. The name: and email: parameters are required because they have no default value, while age: nil is optional. At the call site, the argument names document what each value represents, which reduces mistakes when the order of arguments is not obvious.
def create_user(name:, email:, age: nil)
{ name: name, email: email, age: age }
end
user = create_user(name: "Eve", email: "eve@example.com")
puts user
# Output: {:name=>"Eve", :email=>"eve@example.com", :age=>nil}
user2 = create_user(name: "Frank", email: "frank@example.com", age: 30)
puts user2
# Output: {:name=>"Frank", :email=>"frank@example.com",:age=>30}
Keyword arguments require the caller to specify parameter names, reducing errors from argument order mistakes.
method naming conventions
Ruby has specific conventions for method names:
- Use snake_case:
calculate_total,user_name - End with a question mark (
?) for methods that return boolean:empty?,valid?,includes? - End with an exclamation mark (
!) for dangerous or mutating methods:save!,update!,chomp!
def empty?
@items.length == 0
end
def save!
raise "Cannot save!" unless valid?
# save logic here
end
Calling Methods
You call a method simply by using its name. Ruby provides several ways to pass arguments:
Positional arguments:
Naming conventions like ? and ! help other developers understand what a method does at a glance. Once you have defined a method, you call it by name. Ruby looks up the method in the current scope and executes its body with the arguments you supply. Positional arguments are the simplest calling style: you list the values in the same order as the parameters, and Ruby matches them by position.
result = add(10, 5)
Keyword arguments:
Positional arguments rely on order, which works well for one or two values but can become error-prone with more. Keyword arguments let the caller specify which parameter each value belongs to by name. The call calculate(x: 10, y: 5) makes it obvious that 10 is the x value and 5 is the y value, even if you have not memorized the method’s parameter order. This is especially helpful when reading code you wrote months ago.
result = calculate(x: 10, y: 5)
With parentheses (optional):
Ruby lets you omit parentheses when calling a method, but this feature comes with a trade-off. The bare add 10, 5 reads like natural language, which can make DSL-style code feel cleaner. However, omitting parentheses can also create ambiguity when the method call is nested inside another expression. Most Ruby style guides recommend including parentheses for clarity except in DSL contexts or when calling methods like puts and require that are treated as keywords.
result = add(10, 5)
result = add 10, 5 # also valid
when to use methods
Use methods when you:
- Have code that repeats in multiple places
- Want to give a descriptive name to a block of code
- Need to test individual pieces of functionality
- Want to make your code more readable and maintainable
when not to overuse methods
Avoid creating methods for:
- Trivial one-liners that are clearer inline
- Very specific logic used only once
- Premature optimization—write clear code first, refactor later
Next steps
Methods are the foundation, but Ruby code really comes alive when you combine methods with blocks. Continue with Ruby Blocks and Iterators to see how methods like each, map, and select accept blocks that let you pass behaviour into a method. You can also explore Ruby Classes and Objects to see how methods live inside classes and how method dispatch works in an object-oriented context.
Next, move on to Ruby Strings to see how methods work on real text values. You can also revisit Getting Started with Ruby if you want a quick refresher on the first Ruby syntax patterns.
Summary
Methods are essential for organizing Ruby code. You’ve learned how to:
- Define basic methods with
defandend - Add parameters and default values
- Return values explicitly or implicitly
- Use variable-length and keyword arguments
- Follow Ruby naming conventions
When a method starts handling too many responsibilities, split it into smaller pieces. That keeps each method easier to reason about and makes the call sites read more like a sentence than a pile of instructions.