Skip to content

Conversation

@eregon eregon force-pushed the ruby2_keywords-by-default branch 4 times, most recently from a1093aa to 0297139 Compare January 21, 2020 22:41
@eregon eregon marked this pull request as ready for review January 21, 2020 22:42
@eregon eregon requested review from jeremyevans and mame January 21, 2020 22:42
@eregon
Copy link
Member Author

eregon commented Jan 21, 2020

@mame @jeremyevans This passes test-spec and test-all, and it's a single line change in parse.y.
Please review commit-by-commit as the commit messages explain in details each change.

@eregon eregon force-pushed the ruby2_keywords-by-default branch from 0297139 to c37f995 Compare January 21, 2020 22:47
@eregon
Copy link
Member Author

eregon commented Jan 21, 2020

Of course with this change, calling ruby2_keywords no longer changes anything, so we can remove those calls from the code in this repository (which cleans up the code).

It's not in this PR (yet) to keep it minimal and easy to review. I'm happy to add a commit doing that though. We might possibly also want a $VERBOSE==true warning saying ruby2_keywords no longer has any effect.

Copy link
Contributor

@jeremyevans jeremyevans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation-wise, this looks like the best way to make this change, and should make backporting the feature easy. I'm still not in favor of the change, but if matz approves it, this is definitely the best way to implement it.

@eregon
Copy link
Member Author

eregon commented Jan 23, 2020

Here is the same PR based on ruby_2_7: ruby_2_7...eregon:ruby2_keywords-by-default-27
It's the same commits, just rebased on that branch.

@eregon
Copy link
Member Author

eregon commented Jan 23, 2020

And here we go, the proof that the entire Rails test suite is green with this change on top of 2.7.0!
(the run with my branch is labeled master)
Screenshot from 2020-01-24 00-02-11
rails/rails#38299
https://buildkite.com/rails/rails/builds/66631#_

In fact, it's even more compatible with 2.6, and does not need RUBY_VERSION < "2.7" checks in tests.

And as we can see in https://github.com/rails/rails/blob/69a99e47c063f5d238e6d68f999f44f063aaf478/railties/test/generators/actions_test.rb#L576-L584 people are tempted to use *args, **kwargs delegation in 2.7 but that's broken in 2.7 (& in 2.6 too), so we should only warn delegation (= tell users to migrate) when *args, **kwargs delegation works correctly, in Ruby 3.0+.

@eregon
Copy link
Member Author

eregon commented Jan 23, 2020

Also, this branch would allow a nice cleanup to remove 42 calls to ruby2_keywords in the Rails codebase, if 2.7.0 doesn't need to be supported (2.7.0 already requires a pretty ugly hack for Hash.ruby2_keywords_hash?).
Those ruby2_keywords look like:

ruby2_keywords(:use) if respond_to?(:ruby2_keywords, true)
@eregon
Copy link
Member Author

eregon commented Jan 24, 2020

Also worth noting that this PR based on ruby master seems more compatible than ruby master for Rails tests. I would guess because *args-delegation keeps working and not every library is migrated yet (also considering it's not easy to migrate delegation with 2.7).

Results for ruby master: https://buildkite.com/rails/rails/builds/66628
Results for this branch: https://buildkite.com/rails/rails/builds/66634
activestorage tests fail with ruby master (ArgumentError: wrong number of arguments (given 4, expected 2..3)), but pass with this branch.

* See https://bugs.ruby-lang.org/issues/16463 * This preserves *args-delegation as it worked since Ruby 1.9. * It does not require to change delegation code until it can be changed in a way compatible with older versions (i.e., after Ruby 2 EOL). * This should make it significantly easier to make code compatible with Ruby 2.7, also avoiding confusing warnings in delegation code. * It will also provide precise warnings with instructions on how to migrate delegation in the future, once Ruby 2 is EOL. * The implementation simply sets the ruby2_keywords flag for all args nodes with a *rest argument and no keyword arguments.
@eregon eregon force-pushed the ruby2_keywords-by-default branch from c37f995 to 4a4a7ba Compare February 2, 2020 19:37
@eregon
Copy link
Member Author

eregon commented Feb 2, 2020

I rebased this PR. With the recent changes by @jeremyevans to remove **empty_hash even for ruby2_keywords, this diff is becoming even nicer:

  • No spec is changed.
  • No test is changed, except one where clearly this PR behavior is better.
  • I added new tests for *args-delegation.
@eregon
Copy link
Member Author

eregon commented Apr 2, 2020

Matz said no to this, so I'll close this PR.

Maybe it could become a disabled-by-default flag to help transition, on MRI or other Ruby implementations if there is interest.

It seems like the general direction is to force migrating delegation by 3.0 and to have to use ruby2_keywords. I guess many might skip 2.7 since the delegation warnings are so confusing and so hard to address and in 3.0 it's significantly easier to address delegation in existing codebases as the semantics are better defined. OTOH, non-delegation warnings are good in 2.7 and break hard in 3.0, so there is no good version to migrate all keyword-arguments-related logic.

I feel sad that we have to use an explicit ruby2_keywords and migrate delegation code twice with little help (and even marking all these methods as ruby2_keywords won't be enough for the second migration later once the ruby2_keywords hack is removed), but that's how it is.

@eregon eregon closed this Apr 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants