Skip to content
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

Use Kernel#caller_locations (2.x) #1491

Merged
merged 6 commits into from
Oct 6, 2021
Merged

Conversation

julik
Copy link
Contributor

@julik julik commented Nov 5, 2018

Ruby 2.+ includes a Kernel implementation of caller_locations. This implementation differs subtly from the one in Sinatra, causing breakage when another caller tries to use caller_locations. Specifically, this blows up with Bootsnap as noted in Shopify/bootsnap#183

This means that it is impossible to correctly use Sinatra in some situations when a Sinatra application is mounted within a Rails project that uses Bootsnap - which is now the default.

This PR removes the hand-rolled implementation of caller_locations and instead exposes the Kernel one as a public method. Since Sinatra now mandates Ruby 2.+ there should be no compatibility problems.

@julik
Copy link
Contributor Author

julik commented Nov 5, 2018

For the 1.x - where the issue is the most pressing for us - I will try to open a backport PR.

@julik julik changed the title Use built-in implementation of caller_locations when available Use Kernel#caller_locations if available (2.x) Nov 5, 2018
@julik julik changed the title Use Kernel#caller_locations if available (2.x) Use Kernel#caller_locations (2.x) Nov 5, 2018
Copy link
Member

@namusyaka namusyaka left a comment

Choose a reason for hiding this comment

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

I think this breaks backward-compatibility because your patch doesn't consider excluding files.
Thoughts?

@julik
Copy link
Contributor Author

julik commented Nov 5, 2018

I did think about this but didn't re-add the filtering, primarily because tests stay green. In practice everywhere it is used in Sinatra itself it is only the first caller location that gets used/preserved. Since Sinatra is now shadowing a Ruby builtin, there are 2 courses of action possible:

  • To preserve full backwards compatibility - we would need to implement the "in-hoise" caller_locations under a different name (something like sinatra_caller_locations) so that external tools - Bootsnap and RSpec to name a few - would get the builtin implementation, always
  • Reimplement caller_locations with all the possible overrides and argument semantics as per Kernel implementation, and then try to "spice" it with the customised Sinatra filtering
  • Aim for the intersection of required functionality for Sinatra and the builtin - what this PR proposes

What would be your preference? IMO ending up in a situation where you override a kernel method is undesirable because these usually have quite subtle implementations

@namusyaka
Copy link
Member

Aa you said, our tests passed, but it doesn't mean that your change is safe for all public APIs.
We have some implicit public APIs and it tightens us, but it means the developer may depend on that.
So I have to say the first idea isn't safe changes.

Actually your proposal has a important meaning for improving our ecosystem so I'd like to consider merging this change but it's not now.

I'll go back to the change next week, and then I'm going to rethink the necessity and its history at that time.

Btw, thanks for your contribution.

@julik
Copy link
Contributor Author

julik commented Dec 4, 2018

@namusyaka Did you arrive at a decision by any chance? We are nearing a Rails 5 upgrade and also there is something that might have to happen on the bootsnap side. Should we monkeypatch in the meantime?

@namusyaka
Copy link
Member

Please monkey-patch at this time if necessary.
It's worth to get your change for improving sinatra next major or minor release such as v3.0 or v2.1.

@composerinteralia
Copy link

FWIW, I just ran into this when using ActiveSupport's cattr_accessor inside a class inheriting from Sinatra::Base.

In Rails 6.1 ActiveSupport expects a caller_locations method that can take two arguments, but the one defined in sinatra does not take any arguments. So using cattr_accessor breaks with ArgumentError: wrong number of arguments (given 2, expected 0).

@jkowens
Copy link
Member

jkowens commented Aug 17, 2021

@namusyaka can we move forward with this in v3.0? I think this would be a good reason to release a v3 along with other updates that have been sitting.

@jkowens jkowens requested a review from zzak August 17, 2021 16:03
@vs37559
Copy link

vs37559 commented Sep 13, 2021

@jkowens Is this planned to release anytime soon?

@jkowens jkowens changed the base branch from master to unstable October 4, 2021 01:24
@jkowens jkowens requested a review from olleolleolle October 4, 2021 02:12
@jkowens
Copy link
Member

jkowens commented Oct 4, 2021

@namusyaka @olleolleolle I think I'm good with merging this into the unstable branch for v3.0. Do you have any thoughts or concerns?

julik and others added 5 commits October 3, 2021 22:18
Ruby 2.x+ has a built-in implementation of `caller_locations`,
which differs slightly from the Sinatra implementation of the same.
This removes the customized implementation in favor of the system one
lib/sinatra/base.rb Outdated Show resolved Hide resolved
Copy link
Member

@olleolleolle olleolleolle left a comment

Choose a reason for hiding this comment

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

👍 🏆 !

@jkowens jkowens merged commit 982ad7e into sinatra:unstable Oct 6, 2021
@olleolleolle
Copy link
Member

Yay!

jkowens added a commit that referenced this pull request Feb 2, 2022
Ruby 2.x+ has a built-in implementation of `caller_locations`,
which differs slightly from the Sinatra implementation of the same name.
This removes the customized implementation in favor of the system one

Co-authored-by: Jordan Owens <jkowens@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants