i just tracked down a VERY ANNOYING BUG in the limbo space between ruby and rubygems, holy heck ok hear me out
ruby has an experimental feature known as Ruby::Box, which is essentially a portable version of a global namespace within which you can require files, define "toplevel" constants, etc. it is very cool and i want to use it to have multiple versions of Rouge loaded for the preview site.

it's still experimental, so completely fair to have bugs honestly. what i didn't expect was for:

* rack servers like puma to completely choke on missing constants
* the pry console to just completely crash because it doesn't know what Pry is (???)

but this only happened when the Box feature was enabled with the feature flag RUBY_BOX=1.

after a very long and very confusing time had by all, i made a mini ruby installation in a random folder in /tmp and just started putting print statements in source files.

I honestly would have saved a lot of time by looking at the documentation.

you see, when you run the `pry` executable after installing pry via rubygems or bundler, ruby loads a shebang'd file that essentially does:

#!/path/to/ruby
require "rubygems"
Gem.run_binary_file("pry")

(these are not the real method names, and there's some fiddling about with versions, but this is the gist)

the `require "rubygems"` line is a red herring - it makes it look like the file rubygems.rb, which defines the Gem constant and the method used here, are actually eval'd at runtime.

But it turns out rubygems.rb is evaluated by ruby itself *before any code in the file is run*

*in the root box*.
*not the user box*.

to whit, iff I edit rubygems.rb to add `p Ruby::Box.current` and run a file that just contains

#!/path/to/ruby
raise "lol"

and nothing else, rubygems.rb will happily be evaluated and report that it is in the root box:

#<Ruby::Box:1,root>

this is significant because none of the rest of the code in the file is evaluated in the root box. that's all user-code, so it goes in the user box. starting to see the issue?
augh hecked up the thread
edit: nevermind i was confused on this point

anyways, due to the nature of boxes, this means that the entire Gem module from rubygems.rb belongs to the root box. So when bin/pry calls into that method on Gem to load up the *real* executable from the gem, ...

it evaluates the entire gem in the root box also

OOPS

you might not notice this! your app or program may run just fine in the root box! ...unless it does something like pry and rack do, and eval things on TOPLEVEL_BINDING.

which is explicitly a binding on the user box.

which can't see any constants defined by an eval on the root box.

and suddenly you are in a situation where your .pryrc, your console commands, and your config.ru file *can't see any constants brought in by gem dependencies on the very executable you called them with*

in order for this bug to cause an error, you have to:

* call an executable from a gem, directly and not with `ruby the_file`
* with RUBY_BOX=1
* and that executable must eval text or files in TOPLEVEL_BINDING
* which depend on modules defined in the gem

anyways i'm going to bed and making a bug report in the morning, you all have a great night.
@jneen “I honestly would have saved a lot of time by looking at the documentation” sure is a mood