Issue #16379 has been updated by jeremyevans0 (Jeremy Evans).


I'm against backporting features (not just this particular feature) to already released ruby versions.  For one, not everyone runs on the latest tiny release, and having different feature sets in tiny versions is likely to lead to user confusion.  Users currently have an expectation that tiny releases only include bug fixes, and backporting any features results in a slippery slope.

In regards to `pass_keywords`, this wouldn't even be a backport, this would be a brand new feature, as `pass_keywords` isn't implemented in the master branch.  The rejected pull request that implemented `pass_keywords` doesn't handle the case given as it uses a separate VM frame.

In regards to `...`, it only handles delegation of all arguments, so it is only useful in a subset of argument forwarding cases.  It is also implemented using `ruby2_keywords` internally, so backporting it would require backporting `ruby2_keywords`, which you seem to be against.

----------------------------------------
Feature #16379: Backporting ... to Ruby 2.4 - 2.6 and pass_keywords
https://bugs.ruby-lang.org/issues/16379#change-82881

* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
I've heard quite a few people saying that backporting `...` to Ruby 2.4-2.6 would be a good way to do migration for keyword arguments.
In fact, if we have `...` in Ruby 2.4+, I think `...` could be the way to do 90%+ of delegation in a backward-compatible way, and would be vastly more elegant than a hidden Hash flag (`ruby2_keywords`).

What does the Ruby core team think about that?

I think `...` works nicely for lexical delegation:
```ruby
def delegate(...)
  target(...)
end
```

It can also work for delegating in a separate method by using `...` inside a block inside the method accepting `...`:
https://eregon.me/blog/2019/11/10/the-delegation-challenge-of-ruby27.html#pass_keywords
```ruby
def initialize(...)
  @call_later = -> { target(...) }
end

def call
  @call_later.call
end
```

---

If we don't want to backport `...`, there is also the option to use `pass_keywords` like so:
```ruby
pass_keywords def delegate(*args, &block)
  target(*args, &block)
end
```

```ruby
pass_keywords def initialize(*args, &block)
  @call_later = -> { target(*args, &block) }
end

def call
  @call_later.call
end
```

Which can easily work by making `pass_keywords` a no-op on Ruby <= 2.6 and make `*args` behave like `...` on Ruby 2.7+.

---

I think both of these are easier to understand than `ruby2_keywords`, and both don't need to have any performance trade-off on unrelated code (#16188).

I'd like to have the opinion of the core team on this.
It has been suggested multiple times (notably in my blog post on 10 November), but I have not seen any opinion on this tracker about it.



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>