Add support for anonymous rest and keyword rest argument forwarding

This allows for the following syntax:

```ruby
def foo(*)
  bar(*)
end
def baz(**)
  quux(**)
end
```

This is a natural addition after the introduction of anonymous
block forwarding.  Anonymous rest and keyword rest arguments were
already supported in method parameters, this just allows them to
be used as arguments to other methods.  The same advantages of
anonymous block forwarding apply to rest and keyword rest argument
forwarding.

This has some minor changes to #parameters output.  Now, instead
of `[:rest], [:keyrest]`, you get `[:rest, :*], [:keyrest, :**]`.
These were already used for `...` forwarding, so I think it makes
it more consistent to include them in other cases.  If we want to
use `[:rest], [:keyrest]` in both cases, that is also possible.

I don't think the previous behavior of `[:rest], [:keyrest]` in
the non-... case and `[:rest, :*], [:keyrest, :**]` in the ...
case makes sense, but if we did want that behavior, we'll have to
make more substantial changes, such as using a different ID in the
... forwarding case.

Implements [Feature #18351]
This commit is contained in:
Jeremy Evans 2021-11-19 09:38:22 -08:00
parent 2d2ee338f3
commit f53dfab95c
Notes: git 2021-12-31 07:38:08 +09:00
10 changed files with 146 additions and 21 deletions

View file

@ -441,6 +441,13 @@ Also, note that a bare <code>*</code> can be used to ignore arguments:
def ignore_arguments(*)
end
You can also use a bare <code>*</code> when calling a method to pass the
arguments directly to another method:
def delegate_arguments(*)
other_method(*)
end
=== Keyword Arguments
Keyword arguments are similar to positional arguments with default values:
@ -481,6 +488,13 @@ Also, note that <code>**</code> can be used to ignore keyword arguments:
def ignore_keywords(**)
end
You can also use <code>**</code> when calling a method to delegate
keyword arguments to another method:
def delegate_keywords(**)
other_method(**)
end
To mark a method as accepting keywords, but not actually accepting
keywords, you can use the <code>**nil</code>: