From: "Dan Stevens (IAmAI)" Date: 2008-09-03T22:43:35+09:00 Subject: Re: [QUIZ] Where the Required Things Are (#175) ------=_Part_23103_2561392.1220449714187 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline I've had a go at a solution, but I don't think what I did works properly. Feel free to comment on what's wrong with it. RUBYGEMS = 'rubygems.rb' # Create a copy of the load path ($:) @load_path = Array.new($:) # Replace '.' in @load_path with full directory path @load_path[@load_path.index('.')] = Dir.pwd # Enforcing the require of rubygems before aliasing Kernel#require makes things # less troublesome. begin # If rubygems has been loaded, append the its path(s) @load_path.concat(Gem.path) if require RUBYGEMS rescue LoadError # A LoadError will occur if rubygems isn't installed, but it should be safe # to ignore. end module Kernel alias :old_require :require # Make our own require method that uses '@load_path' variable to find the path # of the file given by 'string' def require(string) old_require string # If 'string' doesn't have an extension if File.extname(string).empty? exts = ['.rb', '.so', '.o', '.dll'] until exts.empty? fname = string + exts.shift path = @load_path.find { |i| File.exists? File.join(i, fname) } return File.join(path, fname) unless path.nil? end else return @load_path.find { |i| File.exists? File.join(i, string) } end raise "If you can read this, Kernel#require was able to find a library " + "named #{string} but #{__FILE__} was not able to. Either there is" + "bug in #{__FILE__} and/or Kernel#require's search method is " + "different to #{__FILE__}'s" end end if $0 == __FILE__ ARGV.each { |a| puts require(a) } end 2008/8/29 Matthew Moss > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- > > The three rules of Ruby Quiz 2: > > 1. Please do not post any solutions or spoiler discussion for this > quiz until 48 hours have passed from the time on this message. > > 2. Support Ruby Quiz 2 by submitting ideas as often as you can! (A > permanent, new website is in the works for Ruby Quiz 2. Until then, > please visit the temporary website at > > . > > 3. Enjoy! > > Suggestion: A [QUIZ] in the subject of emails about the problem > helps everyone on Ruby Talk follow the discussion. Please reply to > the original quiz message, if you can. > > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- > > ## Where the Required Things Are (#175) > > Occasionally, I've taken a look at the source for some Ruby module, > often because there is no manual or man page, or what documentation is > available is outdated or incomplete. Or sometimes I just want to see > how some Ruby stuff is implemented. > > One such example was from the previous quiz: I want to learn more > about the Sys::Uptime module. I have it installed, and the call to > `require 'sys/uptime'` works, but I don't know how to use it. But, > alas, I also don't know where the installed files are located. The > shell command `which` doesn't help here, since the module is unlikely > to be in the shell's executable path. > > What I would like is a script that works like `which` but for Ruby > modules. Examples: > > > ruby modwhich.rb "sys/uptime" > require 'sys/uptime' => > /opt/local/lib/ruby/vendor_ruby/1.8/i686-darwin8.11.1/sys/uptime.bundle > > > ruby modwhich.rb date > require 'date' => /opt/local/lib/ruby/1.8/date.rb > > For extra credit, preserve this behavior when modwhich.rb is the main > program, but slightly different behavior is modwhich.rb is required by > another script: > > > ruby -r modwhich upsince.rb > > require 'sys/uptime' => > /opt/local/lib/ruby/vendor_ruby/1.8/i686-darwin8.11.1/sys/uptime.bundle > require 'date' => /opt/local/lib/ruby/1.8/date.rb > Last reboot: 2008 Aug 22 at 18:49 > > Note that we allow upsince.rb to run as normal; the output of > modwhich.rb is mixed into stdout. > > > -- > Matthew Moss > > ------=_Part_23103_2561392.1220449714187--