You can define a method to accept an arbitrary number of keyword arguments using the double splat (**
) operator:
def say(**args)
puts args
end
say foo: "1", bar: "2"
# {:foo=>"1", :bar=>"2"}
The arguments are captured in a Hash
. You can manipulate the Hash
, for example to extract the desired arguments.
def say(**args)
puts args[:message] || "Message not found"
end
say foo: "1", bar: "2", message: "Hello World"
# Hello World
say foo: "1", bar: "2"
# Message not found
Using a the splat operator with keyword arguments will prevent keyword argument validation, the method will never raise an ArgumentError
in case of unknown keyword.
As for the standard splat operator, you can re-convert a Hash
into keyword arguments for a method:
def say(message: nil, before: "<p>", after: "</p>")
puts "#{before}#{message}#{after}"
end
args = { message: "Hello World", after: "</p><hr>" }
say(**args)
# <p>Hello World</p><hr>
args = { message: "Hello World", foo: "1" }
say(**args)
# => ArgumentError: unknown keyword: foo
This is generally used when you need to manipulate incoming arguments, and pass them to an underlying method:
def inner(foo:, bar:)
puts foo, bar
end
def outer(something, foo: nil, bar: nil, baz: nil)
puts something
params = {}
params[:foo] = foo || "Default foo"
params[:bar] = bar || "Default bar"
inner(**params)
end
outer "Hello:", foo: "Custom foo"
# Hello:
# Custom foo
# Default bar