-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Delegator to pass keyword arguments for Ruby 3.0 #1684
Conversation
Looks like this change isn't compatible with Ruby < 2.7 Would also be great to have a test for this (which fails on Ruby 3.0 until the problem has been fixed) |
Apologies for being a PR newbie.
I will work on providing a test, but maybe an informal explanation will
help in the meantime:
In a before.rb controller file, a call like
before accepted_verbs: [ 'PUT', 'POST' ] do ...
fails in Ruby 3, because the before method in sinatra base.rb L1387
receives the hash
{ accepted_verbs: ['PUT'', 'POST' ] }
in its path parameter, instead of as part of **options where it is
expecting it -- which causes the Mustermann.new method later on to complain
that it doesn't know what to do with a Hash
I believe the origin of the issue is Delegator.delegate not passing
parameters through in a way that Ruby 3 can deal with, hence the changes I
suggested in the PR
I don't really have any idea how to make my proposed changes work also in
Ruby < 2.7
…On Sat, 20 Mar 2021 at 00:48, Patrik Ragnarsson ***@***.***> wrote:
Looks like this change isn't compatible with Ruby < 2.7
Would also be great to have a test for this (which fails on Ruby 3.0 until
the problem has been fixed)
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1684 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACHILEBB3Z4TR3Y33Q2NGULTEPWFJANCNFSM4ZPF5J3Q>
.
|
I'm not sure of the best way to provide you with my suggested test, but if
you want to try it manually it would be something like the following added
to test/delegator_test.rb starting at line 91:
====================
it "delegates before with keyword arguments correctly" do
delegation_app do
set(:foo) do |something|
something
end
before(foo: 'bar') do
:nothing
end
end
end
==================
With the original base.rb (before my changes) this should
- pass on Ruby < 2.7
- pass with a warning on Ruby >= 2.7, < 3.0
- fail on Ruby >= 3.0, producing TypeError: Hash can't be coerced into
Mustermann::Pattern
After my changes, the test should
- pass on Ruby >= 2.7
- among 72 other failures, give a weird ArgumentError on the new line 93
of test/delegator_test.rb, when set(:foo) is called -- on Ruby < 2.7
Hope this helps
On Sat, 20 Mar 2021 at 12:59, Andrew Thomas Blake <
***@***.***> wrote:
… Apologies for being a PR newbie.
I will work on providing a test, but maybe an informal explanation will
help in the meantime:
In a before.rb controller file, a call like
before accepted_verbs: [ 'PUT', 'POST' ] do ...
fails in Ruby 3, because the before method in sinatra base.rb L1387
receives the hash
{ accepted_verbs: ['PUT'', 'POST' ] }
in its path parameter, instead of as part of **options where it is
expecting it -- which causes the Mustermann.new method later on to
complain that it doesn't know what to do with a Hash
I believe the origin of the issue is Delegator.delegate not passing
parameters through in a way that Ruby 3 can deal with, hence the changes I
suggested in the PR
I don't really have any idea how to make my proposed changes work also in
Ruby < 2.7
On Sat, 20 Mar 2021 at 00:48, Patrik Ragnarsson ***@***.***>
wrote:
> Looks like this change isn't compatible with Ruby < 2.7
>
> Would also be great to have a test for this (which fails on Ruby 3.0
> until the problem has been fixed)
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <#1684 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ACHILEBB3Z4TR3Y33Q2NGULTEPWFJANCNFSM4ZPF5J3Q>
> .
>
|
- passes on Ruby < 2.7 - passes with warning on Ruby >= 2.7, < 3.0 - fails on Ruby 3.0
@andrewtblake You can add your test from #1686 to this branch From reading https://eregon.me/blog/2021/02/13/correct-delegation-in-ruby-2-27-3.html it sounds like we need to use At https://github.com/ruby/ruby2_keywords#usage there's an example that is using |
That looks like it will do the trick, thanks. I will work on putting
together a new PR including the test and the ruby2_keywords approach.
…On Mon, 22 Mar 2021 at 11:53, Patrik Ragnarsson ***@***.***> wrote:
@andrewtblake <https://github.com/andrewtblake> You can add your test
from #1686 <#1686> to this branch
From reading
https://eregon.me/blog/2021/02/13/correct-delegation-in-ruby-2-27-3.html
it sounds like we need to use ruby2_keywords
<https://github.com/ruby/ruby2_keywords>. Maybe you can experiment with
it?
At https://github.com/ruby/ruby2_keywords#usage there's an example that
is using define_method
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1684 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACHILECBA3H7IZ6YS2QV7X3TE4VSHANCNFSM4ZPF5J3Q>
.
|
If you have time, I'd appreciate some guidance on where is the best place
to put the gem "ruby2_keywords", "~> 0.0.4" line in Gemfile
…-- should it be inside the if RUBY_ENGINE == "ruby" block? Or above, where gem
"twitter-text", "1.14.7" is?
Also, do you prefer the require 'ruby2_keywords' line to be right above
where it is used, or alternatively at the top of the base.rb file with the
other requires?
Thanks for your help
On Mon, 22 Mar 2021 at 20:42, Andrew Thomas Blake <
***@***.***> wrote:
That looks like it will do the trick, thanks. I will work on putting
together a new PR including the test and the ruby2_keywords approach.
On Mon, 22 Mar 2021 at 11:53, Patrik Ragnarsson ***@***.***>
wrote:
> @andrewtblake <https://github.com/andrewtblake> You can add your test
> from #1686 <#1686> to this branch
>
> From reading
> https://eregon.me/blog/2021/02/13/correct-delegation-in-ruby-2-27-3.html
> it sounds like we need to use ruby2_keywords
> <https://github.com/ruby/ruby2_keywords>. Maybe you can experiment with
> it?
>
> At https://github.com/ruby/ruby2_keywords#usage there's an example that
> is using define_method
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <#1684 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ACHILECBA3H7IZ6YS2QV7X3TE4VSHANCNFSM4ZPF5J3Q>
> .
>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work, I answered your questions about Gemfile/require
lib/sinatra/base.rb
Outdated
|
||
# We need ruby2_keywords to make delegation work correctly on | ||
# ruby2.7 and ruby3 | ||
require 'ruby2_keywords' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would put the require at the top of the file, somewhere at
Lines 4 to 10 in cf40452
# external dependencies | |
require 'rack' | |
require 'tilt' | |
require 'rack/protection' | |
require 'mustermann' | |
require 'mustermann/sinatra' | |
require 'mustermann/regular' |
Gemfile
Outdated
@@ -66,6 +66,7 @@ if RUBY_ENGINE == "ruby" | |||
gem 'commonmarker', '~> 0.20.0' | |||
gem 'pandoc-ruby', '~> 2.0.2' | |||
gem 'simplecov', require: false | |||
gem 'ruby2_keywords', '~> 0.0.4' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Gemfile only holds our test dependencies, this will be a runtime dependency for Sinatra, so it needs to be in the gemspec:
Lines 46 to 49 in cf40452
s.add_dependency 'rack', '~> 2.2' | |
s.add_dependency 'tilt', '~> 2.0' | |
s.add_dependency 'rack-protection', version | |
s.add_dependency 'mustermann', '~> 1.0' |
lib/sinatra/base.rb
Outdated
@@ -1947,6 +1952,7 @@ def self.delegate(*methods) | |||
return super(*args, &block) if respond_to? method_name | |||
Delegator.target.send(method_name, *args, &block) | |||
end | |||
ruby2_keywords method_name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can also avoid needing to use the ruby2_keywords
gem if we do
ruby2_keywords method_name | |
ruby2_keywords(method_name) if respond_to?(:ruby2_keywords, true) |
That seems much cleaner, although apparently the gem is already a
dependency of mustermann 1.1.1
…On Tue, 23 Mar 2021 at 09:29, Patrik Ragnarsson ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In lib/sinatra/base.rb
<#1684 (comment)>:
> @@ -1947,6 +1952,7 @@ def self.delegate(*methods)
return super(*args, &block) if respond_to? method_name
Delegator.target.send(method_name, *args, &block)
end
+ ruby2_keywords method_name
We can also avoid needing to use the ruby2_keywords gem if we do
⬇️ Suggested change
- ruby2_keywords method_name
+ ruby2_keywords(method_name) if respond_to?(:ruby2_keywords, true)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1684 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACHILEH4SCRWZDNLGMHKTFDTFBNPRANCNFSM4ZPF5J3Q>
.
|
lib/sinatra/base.rb
Outdated
@@ -1924,6 +1924,7 @@ class #{self.class} | |||
# inherit all settings, routes, handlers, and error pages from the | |||
# top-level. Subclassing Sinatra::Base is highly recommended for | |||
# modular applications. | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's drop this newline
@andrewtblake if you want you can squash all commits here so it's just one so we get a nicer history FYI I'm not a maintainer so I can't merge this |
Relocate ruby2_keywords gem dependency and `require` line Condition use of ruby2_keywords to avoid introducing gem dependency Drop superfluous newline
Looks good to me! Thanks @andrewtblake and @dentarg 👍 |
Use sinatra PR for ruby-3 compatibility sinatra/sinatra#1684 Remove sinatra Bump bundler version Bump ruby version Temporarily disable rubocop/reek to focus on ruby-3
Fix Delegator to pass keyword arguments for Ruby 3.0
Fix Delegator to pass keyword arguments for Ruby 3.0
When Ruby is upgraded to 3.0, errors result from keyword arguments not being passed correctly through the Delegator
delegate
method. This PR fixes the issue.