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

Do not override Kernel#warn when there is no need #4075

Merged

Conversation

eregon
Copy link
Contributor

@eregon eregon commented Nov 20, 2020

  • On Ruby implementations where https://bugs.ruby-lang.org/issues/17259
    is available, backtrace entries starting with <internal: are ignored
    for Kernel#warn. We can then define RubyGems's Kernel#require with
    such a filename and it will automatically be skipped for Kernel#warn.
  • This is much less fragile (overriding Kernel#warn causes multiple
    issues and is very difficult to do properly) and it is also more
    efficient (the override would walk the stack multiple times).

Based on the idea in #3987 (comment)

cc @deivid-rodriguez

What was the end-user or developer problem that led to this PR?

There were various issues due to monkey patching Kernel#warn, a quick search reveals at least:
#3053
#2588
#2911
and ~12 PRs seem to match Kernel#require: https://github.com/rubygems/rubygems/pulls?q=is%3Apr+Kernel%23warn
(original PR: #2442)

Also as a Ruby implementor, I can say overriding Kernel methods when it's not strictly needed leads to all kind of troubles.
Notably I got some headaches to handle the filtering in TruffleRuby and still let the filtering on RubyGems understand what's going on (it was not enough to just filter twice to give an idea of the complexity).

And of course having subtle behavior differences when passing --disable-gems for Kernel#warn is very confusing (I got tricked by this multiple times).

What is your fix for the problem, implemented in this PR?

This PR is a nice way to not need to monkey-patch at all, and still always skip RubyGems' require when using warn('message', uplevel: 1), for instance at the top of a file to emit a deprecation warning. So it fixes the original problem #2442 without monkey-patching anything.

Make sure the following tasks are checked

@eregon
Copy link
Contributor Author

eregon commented Dec 4, 2020

@deivid-rodriguez Could you or some other maintainer (who should I ping?) review this?
I think it's important to merge this so it can be in Ruby 3.

Copy link
Member

@deivid-rodriguez deivid-rodriguez left a comment

Choose a reason for hiding this comment

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

Looks good to me, just a minor comment but looks fine either way!

lib/rubygems/core_ext/kernel_warn.rb Show resolved Hide resolved
lib/rubygems.rb Show resolved Hide resolved
* On Ruby implementations where https://bugs.ruby-lang.org/issues/17259
  is available, backtrace entries starting with `<internal:` are ignored
  for Kernel#warn. We can then define RubyGems's Kernel#require with
  such a filename and it will automatically be skipped for Kernel#warn.
* This is much less fragile (overriding Kernel#warn causes multiple
  issues and is very difficult to do properly) and it is also more
  efficient (the override would walk the stack multiple times).
@eregon eregon force-pushed the no-kernel-warn-monkey-patch branch from b02c21e to 09726ae Compare December 4, 2020 11:03
@deivid-rodriguez deivid-rodriguez merged commit 058e858 into rubygems:master Dec 7, 2020
@deivid-rodriguez
Copy link
Member

Thanks @eregon!

deivid-rodriguez added a commit that referenced this pull request Dec 7, 2020
Do not override Kernel#warn when there is no need

(cherry picked from commit 058e858)
deivid-rodriguez added a commit that referenced this pull request Dec 7, 2020
Do not override Kernel#warn when there is no need

(cherry picked from commit 058e858)
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.

None yet

4 participants