Ruby method with a (*) signature
ruby
Solution
def a_method(*args)
...
end
Normally, when we write this, we get a list of all of the method's arguments stored in the `args` variable.
def a_method(*)
...
end
This is an anonymous form of the same. We accept any number of arguments but don't wish to give a name to that list variable. Now, we haven't given the list of arguments a name, but we can still splat it into another argument list. So while this isn't legal
def a_method(*)
# Should've just named it in the first place :(
args = *
...
end
this, on the other hand, is
def a_method(*)
another_method(*)
end
and will pass the arguments onto `another_method`. It's equivalent to
def a_method(*args)
another_method(*args)
end
The same can be done with Ruby 3 keyword arguments
def a_method(**)
another_method(**)
end
Note that, if your intention is to forward all arguments, you should use the ellipsis syntax.
def a_method(...)
another_method(...)
end
A lone `*` will act funny when delegating keyword arguments. For instance,
def foo(*args, **kwargs)
p args
p kwargs
end
def bar(*)
foo(*)
end
foo(1, a: 1) # Prints [1] then {:a=>1}
bar(1, a: 1) # Prints [1, {:a=>1}], then {}
When calling `foo` directly, named argument syntax gets passed to `**kwargs`, but when delegating through `bar`, it gets converted into a hash and then passed into `*args`. On top of that, `*` won't forward block arguments either, whereas `...` is your general-purpose "pass all positional, named, and block arguments onward" catch-all.
Problem
On this interesting blog post about pattern matching, there is some code with a method signature of `(*)` ``` class Request < Data.define(:path, :scheme, :format) def deconstruct_keys(*) { path: @path, scheme: @scheme, format: @format } end def deconstruct(*) path.split("/").compact end end ``` This is different than ``` def a_method(*args) ``` I could not find any information in the Ruby docs. What does `def deconstruct_keys(*)` mean? Note This question was mentioned on Ruby Weekly