100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Ruby

Method Arguments and Defaults

Learn how Ruby methods accept required, optional, splat, keyword, and block arguments, and how default values keep call sites flexible and expressive.

Methods & BlocksBeginner9 min readJul 9, 2026
Analogies

Method Arguments and Defaults

Ruby methods can accept several flavors of arguments: required positional arguments, optional arguments with default values, a splat argument that soaks up any remaining positional values, keyword arguments (with or without defaults), a double-splat for arbitrary keyword values, and a trailing block. Understanding how Ruby orders and resolves these when a method is called is essential for writing APIs that are both flexible and predictable. Unlike languages that only support fixed positional signatures, Ruby lets you mix these forms freely, which is why so many standard library and Rails methods accept a small pile of options without forcing callers to remember rigid ordering.

🏏

Cricket analogy: Ruby's mix of required, optional, splat, keyword, and block arguments is like a team sheet that has fixed required players, optional impact substitutes, a pool of reserves, and named specialist roles, all combinable without a rigid fixed order.

Required and optional positional arguments

A required argument has no default and must be supplied by the caller, or Ruby raises an ArgumentError. An optional argument is given a default expression evaluated at call time (not at method definition time), so defaults can reference earlier parameters or even call other methods. Ruby evaluates default expressions left to right, and any optional parameter must generally come after the required ones unless a splat separates the groups.

🏏

Cricket analogy: A required argument raising ArgumentError if missing is like a team sheet being rejected if the captain's name is left blank, while an optional argument's default evaluated at call time is like a reserve player assigned based on who's actually fit that morning.

ruby
def greet(name, greeting = "Hello", punctuation: "!")
  "#{greeting}, #{name}#{punctuation}"
end

greet("Ada")                          # => "Hello, Ada!"
greet("Ada", "Hey")                   # => "Hey, Ada!"
greet("Ada", punctuation: "?")        # => "Hello, Ada?"

def total_price(base, tax_rate: 0.07, shipping: base > 50 ? 0 : 5.99)
  (base + base * tax_rate + shipping).round(2)
end

total_price(80)   # shipping default reads the `base` parameter

Splat, double-splat, and keyword arguments

A single splat parameter (*args) collects any extra positional arguments into an array, which is invaluable for variadic methods like a custom logger or a sum function. Keyword arguments, introduced with a name: syntax, must be passed by name at the call site and can have their own defaults; a required keyword argument is written without a default (name:) and raises ArgumentError if omitted. A double-splat parameter (**opts) gathers any keyword arguments not explicitly named into a hash, which is how many Rails methods accept an open-ended options hash while still documenting the common ones explicitly.

🏏

Cricket analogy: A splat parameter collecting extra positional arguments is like a scorer's tally sheet absorbing every extra run scored off a single over into one array, while a double-splat is like a post-match stats sheet gathering every named metric not explicitly tracked, like strike rate or dot-ball percentage.

ruby
def build_report(title, *sections, author:, tags: [], **metadata)
  {
    title: title,
    sections: sections,
    author: author,
    tags: tags,
    metadata: metadata
  }
end

build_report("Q3 Sales", "Summary", "Charts", author: "Priya", region: "EMEA")
# sections => ["Summary", "Charts"], metadata => { region: "EMEA" }

Since Ruby 2.7+, calling a method that expects keyword arguments with a plain hash as the last positional argument is no longer automatically converted (the old implicit hash-to-kwargs conversion was removed in Ruby 3.0). Use the double-splat explicitly, e.g. some_method(**options_hash), to forward a hash as keyword arguments.

Mutable default values are a classic pitfall shared with Python: def add_item(item, list = []) looks fine, but because the default expression is re-evaluated on every call (unlike Python's one-time default), Ruby actually sidesteps Python's infamous shared-mutable-default bug. Still, be careful when a default references another parameter that could be nil — the default expression will raise a NoMethodError at call time rather than at definition time.

Argument order and forwarding

The canonical parameter order Ruby enforces is: required positional, optional positional, splat, more required positional (post-splat), keyword arguments, double-splat, and finally an explicit block parameter. Ruby 2.7+ also introduced the anonymous forwarding operator ..., which lets a wrapper method forward all arguments -- positional, keyword, and block -- to another method without naming them individually, which keeps decorator-style methods concise.

🏏

Cricket analogy: Ruby's fixed parameter order culminating in a block is like a bowling attack's set sequence: opening bowlers first, then first-change, then part-timers, and finally the specialist spinner brought on last for the tactical finishing touch.

ruby
def instrument(...)
  start = Time.now
  result = perform_work(...)
  puts "took #{Time.now - start}s"
  result
end
  • Optional positional arguments use param = default; default expressions are evaluated fresh on every call.
  • Keyword arguments (name: or name: default) must be passed by name and improve readability at call sites.
  • A splat (*args) collects extra positional arguments into an array; a double-splat (**opts) collects extra keyword arguments into a hash.
  • Since Ruby 3.0, positional hashes are no longer auto-converted to keyword arguments -- use **hash explicitly.
  • Parameter order is fixed: required, optional, splat, post-splat required, keywords, double-splat, block.
  • The ... forwarding operator (Ruby 2.7+) forwards all arguments and the block to another method in one shot.

Practice what you learned

Was this page helpful?

Topics covered

#Ruby#RubyStudyNotes#Programming#MethodArgumentsAndDefaults#Method#Arguments#Defaults#Required#Functions#StudyNotes#SkillVeris