Methods
Reviewed & published by Brayan K
Ruby is a dynamic, beginner-friendly programming language, and methods let you package logic into named, reusable units you can call again and again.
Part of the free Ruby course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.
By the end of this lesson you'll define methods, pass parameters with defaults and keywords, and understand Ruby's implicit return.
What You'll Learn in This Lesson
- Defining methods with def ... end
- Passing positional parameters and arguments
- Default parameter values
- Keyword arguments for self-documenting calls
- Ruby's implicit return and when to use explicit return
- The ? and ! naming conventions
1️⃣ Defining and Calling Methods
You define a method with def, a name, optional parameters in parentheses, and a closing end. The big Ruby idea: the method returns its last evaluated expression automatically — no return needed. Parameters can have default values so callers may omit them.
# Define a method with "def" and close it with "end".
def greet(name)
"Hello, #{name}!" # the LAST expression is returned automatically
end
puts greet("Ada") # -> Hello, Ada!
# Methods can take several parameters.
def add(a, b)
a + b # no "return" keyword needed
end
puts add(2, 3) # -> 5
# Default parameter values are used when an argument is omitted.
def greet_with(name, greeting = "Hi")
"#{greeting}, #{name}!"
end
puts greet_with("Sam") # -> Hi, Sam!
puts greet_with("Sam", "Welcome") # -> Welcome, Sam!2️⃣ Explicit Return, Keyword Args, and Naming
Reach for return only to exit early — like a guard for negative input. Keyword arguments (with a trailing colon) make calls read like labelled forms and free you from remembering argument order. And the trailing ? convention marks methods that answer true/false.
# Ruby returns the LAST evaluated expression automatically.
# Use an explicit "return" only to exit early.
def abs_value(n)
return -n if n < 0 # early return for negatives
n # otherwise return n itself
end
puts abs_value(-4) # -> 4
puts abs_value(9) # -> 9
# Keyword arguments make calls self-documenting (note the colons).
def build_user(name:, role: "member")
"#{name} (#{role})"
end
puts build_user(name: "Lin") # -> Lin (member)
puts build_user(name: "Lin", role: "admin") # -> Lin (admin)
# Methods ending in ? conventionally return true/false.
def adult?(age)
age >= 18
end
puts adult?(20) # -> trueYour turn. Two area methods are written for you — you just need to call them with real numbers. Replace the TODO arguments, then run it.
# 🎯 YOUR TURN — replace each ___, then run with: ruby area.rb
# 1) Define a method that returns the area of a rectangle.
def area(width, height)
width * height # remember: last line is the return value
end
# 2) Define a method with a DEFAULT parameter for a square.
def square_area(side, factor = 1)
side * side * factor # 👉 leave as-is, or experiment
end
# 3) Call them and print the results
rect = area(___) # 👉 replace ___ with 4, 5
sq = square_area(___) # 👉 replace ___ with 3
puts "Rectangle: #{rect}"
puts "Square: #{sq}"
# ✅ Expected output (for 4, 5 and 3):
# Rectangle: 20
# Square: 9Mini-Challenge: A Greeting Machine
Write a greet method that uses a keyword argument formal: to switch between two messages. Run with ruby hello.rb.
# 🎯 MINI-CHALLENGE: a greeting machine.
# Save as hello.rb and run with: ruby hello.rb
#
# 1. Write a method "greet(name, formal: false)" using a keyword argument.
# 2. If formal is true, return "Good day, <name>."
# 3. Otherwise return "Hey <name>!".
# 4. Call it both ways and puts the results.
#
# ✅ Example output:
# Hey Sam!
# Good day, Sam.
# your code hereCommon Errors (and the fix)
- "wrong number of arguments" — You passed too few or too many. Give the method exactly what it declares, or add a default value.
- Returning nil unexpectedly — If the last line is puts ..., the method returns nil. End with the value itself.
- "missing keyword: :name" — A keyword argument without a default is required. Pass it as name: "Lin".
- Forgetting end — Every def needs a matching end.
- Calling before defining — Define the method above the line that calls it; Ruby reads top to bottom.
Pro Tips
- 💡 Keep methods small: a method that does one thing is easier to name, test, and reuse.
- 💡 Splat for many args: def sum(*nums) collects all arguments into an array.
- 💡 Name by behaviour: end predicate methods in ? and mutating ones in !.
📋 Quick Reference — Methods
| Concept | Ruby Syntax |
|---|---|
| Define | def name(args) ... end |
| Default param | def f(x = 1) |
| Keyword arg | def f(name:) |
| Early return | return x if cond |
| Splat (many) | def f(*items) |
| Predicate name | def valid? |
🎉 Lesson Complete!
- ✅ Define methods with def ... end
- ✅ The last expression is returned implicitly
- ✅ Parameters can have default values
- ✅ Keyword arguments make calls self-documenting
- ✅ Use ? for predicates and ! for mutating methods
Practice quiz
Which keywords open and close a method definition?
- function ... end
- def ... }
- def ... end
- method ... end
Answer: def ... end. A method is written def name ... end.
What value does a Ruby method return by default?
- the last evaluated expression
- nil
- the first argument
- true
Answer: the last evaluated expression. Ruby implicitly returns the last expression evaluated.
When do you need an explicit return?
- always
- to return a string
- never; it is illegal
- only to exit a method early
Answer: only to exit a method early. Use return mainly for early exits, like a guard clause.
What is the result of def add(a, b); a + b; end then add(2, 3)?
- nil
- 5
- 23
- an error
Answer: 5. The last expression a + b is returned automatically, giving 5.
How do you give a parameter a default value?
- def f(x = 1)
- def f(x: 1)
- def f(x => 1)
- def f(x ?= 1)
Answer: def f(x = 1). A positional default uses = like def f(x = 1).
How are keyword arguments written and passed?
- with an asterisk
- in square brackets
- with a trailing colon, like name:
- with a leading @
Answer: with a trailing colon, like name:. Keyword arguments use a trailing colon and are passed by name.
By convention, a method name ending in ? signals that it:
- mutates the object
- returns a boolean
- is private
- takes no arguments
Answer: returns a boolean. A trailing ? marks a predicate returning true or false.
By convention, a trailing ! on a method name signals it:
- returns nil
- is faster
- is deprecated
- is a dangerous or mutating version
Answer: is a dangerous or mutating version. A trailing ! warns of a mutating or more aggressive variant, like sort!.
Why might a method return nil unexpectedly?
- it has too many arguments
- its last line is a puts, which returns nil
- it uses keyword arguments
- it has a default value
Answer: its last line is a puts, which returns nil. puts and print return nil, so ending on them returns nil.
What does def sum(*nums) collect into nums?
- a single value
- a hash of keywords
- all the arguments as an array
- a block
Answer: all the arguments as an array. The splat *nums gathers all positional arguments into an array.
Continue this course
- Previous: case/when Conditionals
- Next: Blocks — Pass chunks of code to methods with do...end and curly braces
- Quick reference: Ruby cheat sheet
Frequently asked questions
Do I need the 'return' keyword in Ruby methods?
Usually not. Ruby automatically returns the value of the last expression evaluated in a method, so def add(a, b); a + b; end returns the sum without writing return. You only need an explicit return to exit a method early — for example, return nil if input.empty? as a guard at the top. Idiomatic Ruby leans on implicit return and reserves return for early exits.
What's the difference between positional, default, and keyword arguments?
Positional arguments are matched by order: greet("Sam", "Hi") fills name then greeting. Default arguments give a fallback when omitted: greeting = "Hi". Keyword arguments are passed by name with a colon, like build_user(name: "Lin", role: "admin"), which makes calls self-documenting and order-independent. Keyword arguments are especially valuable when a method has several options, because the caller can see exactly what each value means.
What do the ? and ! at the end of method names mean?
They are conventions, not syntax rules. A trailing ? signals the method returns a boolean, like empty? or adult?. A trailing ! signals a 'dangerous' or mutating version that changes the object in place or behaves more aggressively, like sort! (sorts the array itself) versus sort (returns a new sorted array). Following these conventions makes your own methods instantly understandable to other Ruby developers.
Why is my method's return value nil?
The most common cause is that the last line of the method is a puts or print, which themselves return nil. So def shout(s); puts s.upcase; end prints the text but returns nil. If you want the method to return the value, make the last expression the value itself — for example end with s.upcase rather than puts s.upcase. Use puts at the call site instead of inside the method when you want both.