Ruby's Anonymous Parameter Forwarding
Ruby has some anonymous argument forwarding syntax. This post summaries them, but Victor Shepelev has a great post going into detail that is well worth a read.
Positional Argument Forwarding
Forward all positional arguments directly to another method without allocating a local variable in the forwarding method.
def foo(x, y)
pp [x,y]
end
def bar(*)
foo(*)
end
bar(1,2)
bar
will forward all positional parameters to foo
, foo
will check the arity of what is received.
Named Argument Forwarding
Forward all named arguments directly to another method without allocating local variable in the forwarding method.
def foo(x:, y:)
pp [x, y]
end
def bar(**)
foo(**)
end
bar(x: 1, y: 2)
Block Forwarding
Forward a block directly to another method avoiding the block → proc → block conversion which is expensive.
def foo(&block)
yield if block_given?
end
def bar(&)
foo(&)
end
bar { puts 'Hello world' }
Combinations of all
The positional, named, and block parameters can be forwarded separately (or together) using a combination of the above.
def foo(x, y)
pp [x, y]
end
def bar(x:, y:)
pp [x,y]
end
def baz(&block)
yield if block_given?
end
def qux(*, **, &)
foo(*)
bar(**)
baz(&)
end
All Argument Forwarding
Forward all arguments directly.
def foo(a, b, x:, y:, &block)
pp [a, b, x, y]
yield if block_given?
end
# yes, 3 dots, this is not an omission
def bar(...)
foo(...)
end
Curiosities
Prevent any named parameters
Ruby does some auto packing of hashes as the last parameter to methods white positional arguments. This was a pseudo way of using named parameters before their formal introduction.
def foo(values)
pp values
end
foo(x: 1, y: 2)
#=> {:x=>1, :y=>2}
There is only argument, the parameters get packed into a hash. This was quite a common mechanism for receiving so-called options
hashes but should be considered a legacy approach.
To avoid any confusion, it is possible to explicitly declare a method will not take anything that might be confused as a named parameter.
def foo(x, **nil)
pp x
end
foo(x: 1)
# => no keywords accepted (ArgumentError)
Blocks
Blocks do not allow argument forwarding at all.
Member discussion