liveBook · Manning

Optional function argument

As explained in The Well-Grounded Rubyist, Fourth Edition

An optional parameter is a method parameter whose value can be omitted because a default value is specified.

An optional argument lets a Ruby method be called without a value for every parameter. A default-valued parameter uses the value in its definition when the caller omits that argument; a supplied value takes its place. A starred parameter (`*args`) is optional in a different way: it collects any extra positional arguments into an array, which is empty if there are none. section 2.4.1

A default versus a catch-all

def report(name, count=1, *notes) p name, count, notes end report("Ada") # "Ada", 1, [] report("Ada", 3, "urgent") # "Ada", 3, ["urgent"] `count` has a fallback value. `notes` has no fallback expression: its starred parameter receives an array of whatever arguments remain. section 2.4.1 section 2.4.3

Argument binding gets more interesting when required parameters appear on both sides of optional ones. Ruby assigns the required parameters first, including those at the right edge. Of the arguments left in the middle, a default-valued parameter can receive a value; a starred parameter collects the rest. If no value remains for a default-valued parameter, its default applies. Omitting a required argument still raises `ArgumentError`. section 2.4.2

>> args_unleashed(1,2,3,4,5)       1
1
2
[3]   
4
5
=> [1, 2, [3], 4, 5]
>> args_unleashed(1,2,3,4)        2
1
2
[]
3
4
=> [1, 2, [], 3, 4]
>> args_unleashed(1,2,3)     3
1
1
[]
2
3
=> [1, 1, [], 2, 3]
>> args_unleashed(1,2,3,4,5,6,7,8)      4
1
2
[3, 4, 5, 6]
7
8
=> [1, 2, [3, 4, 5, 6], 7, 8]
>> args_unleashed(1,2)                            5
wrong number of arguments (given 2, expected 3+) (ArgumentError)

Compare calls with three, four, and five arguments: the right-hand required parameters keep their values, while the default-valued parameter and catch-all array change. section 2.4.2

Parameter order must make that assignment possible. Required positional parameters can be on the left, the right, or both, with optional positional parameters between them. A starred catch-all cannot come before a default-valued positional parameter: after the catch-all collected the remaining arguments, there would be no sensible way to decide whether the later parameter should receive one. section 2.4.3

Keyword arguments have their own optional form. In `def options(a: 1, b: 2)`, calling `options` uses both defaults; calling `options(b: 10)` replaces only `b`. Unlike positional arguments, keywords need not be supplied in parameter order. A keyword written without a default, such as `b:`, is required. section 9.3.8

How The Well-Grounded Rubyist, Fourth Edition covers it

How deep it goes
Works through defaults, starred arrays, mixed-parameter binding, and invalid ordering; treats keyword arguments separately.
Examples
Compares method calls that use defaults, override them, fill catch-all arrays, or fail for too few arguments.
What it assumes
Assumes basic method definitions and calls; distinguishes parameters from supplied arguments before developing optional forms.
What you can do after
Build it from scratch using valid Ruby signatures with optional positional or keyword parameters, and predict argument assignments.
How it connects
Connects method parameters and local-variable assignment with required arguments, arrays, and keyword arguments.

Also explained in

Compare how 4 books explain optional function argument →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Well-Grounded Rubyist, Fourth Edition. The section links point to the parts of the book it draws on.