-
Notifications
You must be signed in to change notification settings - Fork 25
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
Undefine VERSION in gemspec to avoid namespace pollution between multiple MemoWises #370
base: main
Are you sure you want to change the base?
Conversation
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 :)
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #370 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 2 3 +1
Lines 190 192 +2
Branches 90 90
=========================================
+ Hits 190 192 +2 ☔ View full report in Codecov by Sentry. |
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.
Update...
Thinking about this more. This could introduce a bug where another require / require_relative will not have the effect of the laoding the file because it thinks the file has already been loaded, and it doesn't know that you've removed the constant... thus the VERSION constant may never get loaded.
I do think it should be load
here.
Basically, you want to avoid the "tracking" side effect of require because you're going to remove the |
@pboling that's what I expected to happen, but I wasn't able to reproduce it locally. I suspect I had a bug in my setup though—are you able to reproduce the issue you described? |
Ooooh. Looking into this more deeply...
(According to AI Llama 2.5 4B 🗡️ ) |
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.
You should be fine with require_relative
. 💯
I do think there is a cognitive benefit to |
And that's quite enough bike shedding from me. 👯 |
This is false. I just tried using |
Wow. So AI lied to me. :). Glad to know my original thinking was correct. I now remember when I operationalized the load paradigm for my gems I wanted to use |
For context, I tried reproducing the issue with this
and this test Ruby file:
|
Yep. Playing with this myself, and I think there are two paths. First, the paranoid path, which is what I've started down, but haven't committed to:
Second, the hopeful path:
I can't fault either choice. I've not used the |
@pboling can you explain what you mean by
I don't think I follow. |
require / require_relative track what is loaded, so they will be careful to not reload the same file twice. If I didn't make the point very clearly that I was going for, which is this: I think with the final wrap parameter That's what I'm going to try out now. |
@pboling gotcha, so something like this? Module.new.tap { |mod| load("lib/memo_wise/version.rb", mod) }::MemoWise::VERSION |
Recent versions of Ruby are able to pass a module, instead of a simple true/false wrap param, ever since this PR: ruby/ruby#4986 https://users.aalto.fi/~tontti/posts/ruby-by-examples/ruby-catching-anonymous-module/ So, my load with wrap param idea isn't viable for libraries that need old Ruby support. Thanks for this discussion! |
@JacobEvelyn only saw your response after my previous reply, but yes. That will work for gems that target recent versions of Ruby only. |
require_relative "lib/memo_wise/version" | ||
gem_version = MemoWise.send(:remove_const, :VERSION) |
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.
So the problem now is if using require_relative, and then removing the constant, the file will not be reloaded later, because we've determined that it does track / does not reload, and the constant will remain removed. I'm not sure how this could work @JacobEvelyn
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 guess I'm full circle to: it needs to use load
, and can optionally use the wrap
param if on a new enough version of Ruby.
Thinking about this more... still. You made this PR so that you could isolate the versions of libraries in the same namespace. Your solution is to remove the constant. This works, however, the constant remains removed, and the version.rb file will not be reloaded by the gem. This means that Your example in this comment is working but only because when you load the gem with But I expect that there are scenarios where the gemspec and the gem could both be loaded, and in those scenarios, it could break, by not having a VERSION anymore, if something tried to reference it. |
Aha! https://bundler.io/guides/bundler_in_a_single_file_ruby_script.html The example for Bundler inline is exactly this type of scenario which breaks because the gemspec and the gem are loaded in the same context! Below I've only changed it to reference MemoWise, but otherwise it is the same as the canonical example from bundler.io linked above.
The result of running this:
It blows up because it is relying on the If you use |
5b2e31e
to
b06f1c6
Compare
Hmm @pboling when I try your code above (with
|
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.
LGTM
Typo. |
memo_wise.gemspec
Outdated
# spec.version = Module.new.tap do |mod| | ||
# load("lib/memo_wise/version.rb", mod) | ||
# end::MemoWise::VERSION | ||
load "lib/memo_wise/version" |
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.
load "lib/memo_wise/version" | |
load "lib/memo_wise/version.rb" |
b06f1c6
to
9d94aec
Compare
…iple MemoWises This commit updates `memo_wise.gemspec` to undefine the `MemoWise::VERSION` constant after it is read, as first suggested in simplecov-ruby/simplecov#557 (comment). Before this change, accessing `MemoWise::VERSION` immediately after the `doff_and_don` call in `benchmarks.rb` gives the version of the gem pulled from GitHub, even though `doff_and_don` should mean nothing is in the `MemoWise` namespace. After this change, accessing `MemoWise::VERSION` there gives this error as we expect: ``` uninitialized constant MemoWise (NameError) ```
9d94aec
to
642ee28
Compare
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.
LGTM
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.
LGTM
This commit updates
memo_wise.gemspec
to undefine theMemoWise::VERSION
constant after it is read, as first suggested insimplecov-ruby/simplecov#557 (comment).
Before this change, accessing
MemoWise::VERSION
immediately after thedoff_and_don
call inbenchmarks.rb
gives the version of the gem pulled from GitHub, even thoughdoff_and_don
should mean nothing is in theMemoWise
namespace. After this change, accessingMemoWise::VERSION
there gives this error as we expect:Before merging:
Copy the table printed at the end of the latest benchmark results into theREADME.md
and update this PRIf this change merits an update toCHANGELOG.md
, add an entry following Keep a Changelog guidelines with semantic versioning