[Rubygems-developers] Gem autoloading problems
drbrain at segment7.net
Thu Apr 17 23:23:47 EDT 2008
On Apr 16, 2008, at 20:11 PM, Donavan Pantke wrote:
> On Wednesday 16 April 2008 10:05:01 pm Donavan Pantke wrote:
>> So, we were messing around with Passenger for rails recently, and
>> ran into
>> some behavior that I think needs to be addressed, but I'm not sure
>> Gems, I think as of 1.0, automatically activates a gem's
>> dependencies based
>> on what its spec says.
AFAIK, this has always been true. I checked back to 0.9.0 as that's
the oldest tag I have checked out.
>> However, the gem itself has no control over this. This
>> makes life really hard on systems that need specific handling. In
>> the case
>> of Passenger, the rails gem is loaded based on the version
>> requested, and more
>> than one can be loaded (the process forks before rails gets loaded,
>> multiple versions to be in memory and accessible). However, if the
>> has rails in it, activating passenger means that rails
>> automatically gets
>> activated, and so any further rails activation with a different
>> fails. However, the gemspec is entirely correct in that it needs
>> _some_version of rails, but it really needs to do the activating of
>> dependency itself.
Can it not fork and exec if it is going through the setup of Rails for
each child anyway?
>> The first question I have is, what mechanism can be made available
>> to avert
>> activating a dependent gem until the gem actually needs it?
> I took a look back, and prior RubyGems had an autorequire option,
> that was
> false by default. However, this behavior is not only true by
> default, but
> there's no longer even a way of disabling it.
autorequire is a separate feature from before RubyGems hooking into
Kernel#require. It has nothing to do with activation of dependencies.
> I'm thinking that given the new codebase, the best way of carrying
> this behavior is by extending Gem::Dependency and add_dependency to
> allow for
> disabling autoloading.
Even with such a feature it is too easy to run into the same problem.
Given gems a-1, a-2 and b-1 that depends on any version of a, and a/
some_file.rb existing in both versions of gem a.
# at this point, only b-1 is activated.
# at this point, b-1 and a-2 are both activated,
# because b/some_file.rb required a/some_file.rb
gem 'a', '1' # raises exception
> This way the developer could control autoloading on a
> per-dependency basis.
A user of RubyGems can already control which gem gets activated with
Kernel#gem. However, it is up to the user to activate the gems they
need in dependency order. `gem lock` can help with this.
> This handles especially well the case where a gem has
> to turn off certain dependencies, but more often than not
> autoloading is
AFAIK, this case has never come up before...
More information about the Rubygems-developers