Defining Methods in Ruby
How to write your own methods -- default arguments, keyword arguments, and Ruby's implicit return.
2 min read
Methods are how you package up behavior into a name you can call again. Ruby's method syntax is compact, with a few conveniences worth learning early.
The basics
def greet(name)
"Hello, #{name}!"
end
puts greet("Ada") # Hello, Ada!def starts a method, end closes it — no curly braces. Notice there's no return keyword here: Ruby methods implicitly return the value of the last evaluated expression. return still exists and is used for early exits, but for a method's final value, most idiomatic Ruby leaves it off.
def add(a, b)
return a + b # works, but the `return` is unnecessary here
end
def add(a, b)
a + b # idiomatic: implicit return
endDefault arguments
def greet(name, greeting = "Hello")
"#{greeting}, #{name}!"
end
greet("Ada") # "Hello, Ada!"
greet("Ada", "Welcome") # "Welcome, Ada!"Default values are evaluated left to right, and can even reference earlier parameters:
def rectangle_area(width, height = width)
width * height
end
rectangle_area(4) # 16 -- height defaults to width
rectangle_area(4, 6) # 24Keyword arguments
For methods with several parameters, positional arguments get hard to read at the call site. Keyword arguments fix that:
def create_user(name:, role: "member", active: true)
"#{name} (#{role}), active: #{active}"
end
create_user(name: "Ada", role: "admin")
# "Ada (admin), active: true"The trailing : in the parameter list (name:) marks it as a required keyword argument; role: "member" gives it a default, making it optional. Calling create_user(name: "Ada") works, but calling create_user("Ada") — without the keyword — raises an ArgumentError, since positional and keyword arguments aren't interchangeable.
Splat and double-splat: variable numbers of arguments
def sum(*numbers)
numbers.reduce(0) { |total, n| total + n }
end
sum(1, 2, 3) # 6
sum(1, 2, 3, 4, 5) # 15
def build(**options)
options.each { |k, v| puts "#{k}: #{v}" }
end
build(color: "red", size: "large")*numbers collects any number of positional arguments into an array; **options collects any number of keyword arguments into a hash. You'll see both a lot in library and framework code that needs to accept flexible input.
Question marks and bangs in method names
By convention (not enforced by the language beyond allowing these characters), a method ending in ? returns a boolean (empty?, even?), and a method ending in ! indicates a "more dangerous" version of a similarly-named method — usually one that mutates the receiver in place rather than returning a new copy:
name = " ada "
name.strip # returns a new stripped string, `name` unchanged
name.strip! # mutates `name` in place, returns the mutated string (or nil if unchanged)Both of these conventions are worth adopting in your own methods — Ruby developers rely on them to guess what an unfamiliar method does before reading its implementation.
Test what you just learned
4 quick questions. Get all of them right to unlock the next lesson.
You can take the quiz without an account — logging in just lets your result count toward your progress.