From: Eric Hodel Date: 2007-07-25T15:12:17+09:00 Subject: Re: Import gem to Ruby 1.9 On Jul 24, 2007, at 19:53, NAKAMURA, Hiroshi wrote: > This mail is for the topic '4. What $LOAD_PATH order should be?' > > Eric Hodel wrote: > >> 4-2. after requiring rubygems? > >> [-I, ENV_RUBYLIB, SITELIBDIR, RUBYLIBDIR, ., GEMs] or > >> [-I, ENV_RUBYLIB, SITELIBDIR, GEMs, RUBYLIBDIR, .] or > >> [-I, ENV_RUBYLIB, GEMs, SITELIBDIR, RUBYLIBDIR, .] > >> > >> - the first one is the current RubyGems behavior and it > should not be > >> changed as far as RubyGems team do not change it. the > behavior > >> must have been polished up in several years. > > > > Actually, the last one is current default: > > > > [-I, ENV_RUBYLIB, GEMs, SITELIBDIR, RUBYLIBDIR, .] > > > > This works best for developers who want to work on multiple gems at > > once, since they can use ruby -I to source the development version > > instead of the gem version. > > I may misunderstand custom_require.rb. I'm seeing custom_require.rb > revision 1285. > > # We replace Ruby's require with our own, which is capable of > # loading gems on demand. > # > # When you call require 'x', this is what happens: > # * If the file can be loaded from the existing Ruby loadpath, it > # is. > # * Otherwise, installed gems are searched for a file that matches. > # If it's found in gem 'y', that gem is activated (added to the > # loadpath). > # > # The normal require functionality of returning false if > # that file has already been loaded is preserved. The work of adding the gem's require_paths to $LOAD_PATH happens in Gem::activate. > Custom 'require' at first try to load the specified feature name from; > [-I, ENV_RUBYLIB, SITELIBDIR, RUBYLIBDIR, .] > When it raises LoadError then add GEMs at the top of $LOAD_PATH and > try > to load the feature from; > [GEMs, -I, ENV_RUBYLIB, SITELIBDIR, RUBYLIBDIR, .] The behavior you describe is how 0.9.2 and previous worked. > I concaticated 2 arys and called Array#uniq (I hope Array#uniq > keeps its > order in the future, too). Is this wrong? I have experienced problems where gems were activated despite the files being present in the -I path. This is a developer-only problem. I believe my problems involved dependent gems. When RubyGems activates a gem, it also activates all its dependencies. With GEMs before -I, the gem version can get loaded instead of the -I version. With GEMs after -I, the -I version will always be preferred. I would need to experiment to reproduce the behavior I was seeing. > And when we call 'gem "soap4r"' explicitly, the $LOAD_PATH is; > [GEMs, -I, ENV_RUBYLIB, SITELIBDIR, RUBYLIBDIR, .] > isn't it? In 0.9.2, and earlier, this is correct. Now RubyGems looks for SITELIBDIR and inserts the gem's require_paths before it: $LOAD_PATH.insert($LOAD_PATH.index(sitelibdir, *require_paths)) See line 270-277 of lib/rubygems.rb. (Hrm, line 268 may be wrong.) > I should have wrongly summarized the problem. Can you sort out a > problem about $LOAD_PATH? > > >> - maybe I (NaHi) is the only person who have a very hard time > with > >> this behavior in soap4r-ML. it's because soap4r is the > only lib > >> which is gem-ed and located in RUBYLIBDIR. that's exactly > why I > >> run this thread. > > > > If soap4r were unbundled, would this matter anymore? (I forgot the > > details of the problems of soap4r in RUBYLIBDIR and soap4r gem.) > > No, it won't be the matter anymore. So the followings are just an > explanation what was happened. > > Say an user gets ruby/1.8.6 (based on soap4r-1.5.5). Then installs > soap4r-1.5.6 from tarball later (files are copied to site_lib dir). > Finally moves to RubyGems and installs soap4r-1.5.7 as a gem. > > soap4r-1.5.5 has a feature 'soap/a'. > soap4r-1.5.6 adds new feature 'soap/b'. > soap4r-1.5.7 adds another new feature 'soap/c'. > > soap/c depends on soap/b. soap/b depends on soap/a. > soap/a and soap/b are updated in each new version. > > /usr/lib/ruby/1.8/soap/a # soap4r-1.5.5 > /usr/lib/ruby/1.8/site_ruby/soap/a # soap4r-1.5.6 > /usr/lib/ruby/1.8/site_ruby/soap/b # soap4r-1.5.6 > /usr/lib/ruby/gems/1.8/gems/soap4r-1.5.7/lib/soap/a # soap4r-1.5.7 > /usr/lib/ruby/gems/1.8/gems/soap4r-1.5.7/lib/soap/b # soap4r-1.5.7 > /usr/lib/ruby/gems/1.8/gems/soap4r-1.5.7/lib/soap/c # soap4r-1.5.7 > > Imagine what is loaded when the user runs 'require "soap/c"'. > Thankfully there's an easy answer how to avoid this; to load the > consistent feature versions, add 'gem "soap4r"' somewhere in a > program. On require 'soap/c' you should get 1.5.7 features. On require 'soap/b' then 'soap/c', problems may result without 'gem "soap4r"' first. > Once an user found this answer, it gets easier to track down a loader > problem in soap4r-ml. The rest I want to know is where 'gem "soap4r"' > should be added in RoR environment... (I've not yet been a RoR user.) config/environment.rb is the correct place in RoR. -- Poor workers blame their tools. Good workers build better tools. The best workers get their tools to do the work for them. -- Syndicate Wars