From: Austin Ziegler Date: 2005-03-05T00:43:45+09:00 Subject: Re: ruby gems, and the require problem (was Re: RAA Status & b) On Fri, 4 Mar 2005 23:37:50 +0900, Sam Roberts wrote: > Guys, > > Imagine going to the perl community and saying: > > We have this great new feature to add to the installation tool, > versioning! Sam, hit pause. * Ruby did not have a standard installation and packaging tool prior to RubyGems. Period. Therefore, your analogy here is completely off base. I *agree* with you regarding the use of RUBYOPT. I'm personally quite annoyed that the Windows installer sets RUBYOPT at all, even if it is a selectable option now (at my insistence). I've said as much in a lot of places, including recently. I disagree with you regarding the alternative require mechanism, but also have pointed out that ultimately this stuff is planned to go away. The sooner, the better. RubyGem versioning is a good thing and is a way of solving the major problems of CPAN. There are layers that can be placed on top of the RubyGem versioning, and there are other things that can be done to simplify things (e.g., if RubyGems went transactional, took ownership of files, then it could install in site_ruby without any problems, just like RPA). [...] > Quoting jim@freeze.org , on Fri, Mar 04, 2005 at 02:57:11PM +0900: >> * Sam Roberts [2005-03-04 14:37:28 >> +0900]: >>> Code written with the require_gems won't work for people who >>> don't have gems, even if they have the libraries. >> >> Is it really that much trouble to write: >> >> begin >> require 'some-lib' >> rescue LoadError >> require 'rubygems' >> require 'some-lib' >> end > Multiply that code by 6 if I bring in 6 libs, any of which could > have been installed by the user with or without gems. Do you still > think its not that much trouble? Nope. Once RubyGems is loaded once, then it isn't a big deal. In Ruwiki (a very complex load situation with a complex layout), I did the following: 1) Try to load Ruwiki from the local directory structure (e.g., ./lib/ and ../lib/). 2) Try to load Ruwiki from the directory structure of the running script (e.g., File.dirname($0)/lib and File.dirname($0)/../lib). 3) Try to load Ruwiki from the directory structure of the current file (e.g., File.dirname(__FILE__)/lib and File.dirname(__FILE__)/../lib). 4) Try to load Ruwiki from an unmodified $LOAD_PATH, e.g., site_ruby. 5) Try to load Ruwiki from Rubygems. 6) Fail hard. This is *far* more complex than most scripts will ever need, and it depends on the fact that Ruwiki is delivered as: bin/ruwiki_servlet lib/ruwiki/... ruwiki.cgi So most often with the tar distribution, you'll run ruwiki_servlet with: ruby bin/ruwiki_servlet Because the tar distribution is intended to be deployed directly in a public HTML environment, it can be run with the ruwiki.cgi in the current directory. But it's possible for other configurations, too. The cases required for most applications with a recommended layout of executables in bin/ and the library in lib/ are: 1) Try to load from the local directory structure (e.g., ../lib). 2) Try to load from an unmodified $LOAD_PATH, e.g., site_ruby. 3) Try to load Ruwiki from Rubygems. 4) Fail hard. The code to do this would be: load_state = 1 $LOAD_PATH.unshift "#{Dir.pwd}/../lib" begin require 'library' rescue LoadError $LOAD_PATH.shift if load_state == 1 load_state += 1 require 'rubygems' if load_state == 3 raise if load_state == 4 retry end This is still for a complex situation, though. It could be as simple as: begin require 'rubygems' rescue LoadError nil end require 'lib1' require 'lib2' require 'lib3' That way, you get the gem version if it's installed, and people don't complain. Again, this is for application distribution, and I hope that it goes away with the integration of RubyGems in Ruby. The sooner the RubyGems team can hit 1.0, though, the more likely it will be that Matz accepts it into the core and we can even get rid of (some of) these hacks. More than most people, I *know* this problem because of my insistence that Ruwiki will be distributed as a .tar.gz, a RubyGem, and an RPA package and all three are first-class citizens in the eyes of Ruwiki. Just don't mix the packaging systems right now (it's ugly). [...] > You deploy things on customer sites, right? When those customers > reinstall ruby using the new great ruby gems installer, and all > the scripts you wrote last year fail, are you looking forward to > "easily" fixing all those scripts and redeploying them, instead of > adding a cool feature to PDFWriter? I've written my applications defensively and extensively documented my libraries. I go to extra effort to make sure that normal installs, Gem installs, and RPA installs all Just Work. >> If it's *not* an application script, then, well, they *know* it's >> a gem, so they can do "require 'rubygems'" before requiring >> net/mdns. > Sure, and then publish their script. Next guy who runs it, it > dies. That's not *your* problem as the net/mdns publisher. Sorry, but it's not. Don't try to own problems that aren't yours, ultimately. The RPA-process would hopefully catch some of these things, and the chances are that personA who published netdms-consumer would probably publish it as ... a gem. Ultimately, I agree with you. Ruby needs RubyGems in the core as a replacement to require without doing 'require "rubygems"'. But it does solve a very real problem, and it solves it reasonably well. -austin -- Austin Ziegler * halostatue@gmail.com * Alternate: austin@halostatue.ca