Ruby's module search path

Is there an easy way to discover the path to a “require”-ed module (assuming it’s a .rb file)?

Ie, is there some way to find out where the interpreter would find fred.rb if I said

require ‘fred’

TIA

Harry O.

You may want to look at rextra… I found this

def required
result =
$".each do |file|
$:.each do |path|
if File.exists?( path + ‘/’ + file )
result << (path + ‘/’ + file)
next
end
end
end
result
end

irb(main):001:0> require ‘rextra’
…/rextra.rb:126: warning: *' interpreted as argument prefix ../rextra.rb:369: warning: ’ interpreted as argument prefix
(eval):4: warning: *' interpreted as argument prefix (eval):4: warning:
’ interpreted as argument prefix
(eval):4: warning: *' interpreted as argument prefix (eval):4: warning: ’ interpreted as argument prefix
(eval):4: warning: *' interpreted as argument prefix (eval):4: warning:
’ interpreted as argument prefix
=> true
irb(main):002:0> required
=> [“/home/neoneye/stow/ruby/lib/ruby/1.8/irb.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/e2mmap.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/irb/init.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/irb/context.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/irb/workspace.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/irb/extend-command.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/irb/ruby-lex.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/irb/slex.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/irb/ruby-token.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/irb/input-method.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/i386-freebsd5.1/readline.so”, “/home/neoneye/stow/ruby/lib/ruby/1.8/irb/locale.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/tempfile.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/delegate.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/tmpdir.rb”, “./rextra.rb”, “/home/neoneye/stow/ruby/lib/ruby/1.8/i386-freebsd5.1/st
ringio.so”]
irb(main):003:0>

···

On Wed, 24 Mar 2004 11:32:47 +0900, Harry Ohlsen wrote:

Is there an easy way to discover the path to a “require”-ed module (assuming it’s a .rb file)?

Ie, is there some way to find out where the interpreter would find fred.rb if I said

require ‘fred’


Simon Strandgaard

Simon Strandgaard wrote:

You may want to look at rextra… I found this

def required
result =
$".each do |file|
$:.each do |path|
if File.exists?( path + ‘/’ + file )
result << (path + ‘/’ + file)
next
end
end
end
result
end

From the output, I’m guessing $" is the list of requires that have been executed so far?

I couldn’t find that one in Ruby In A Nutshell … that’s not to say it isn’t in there, of course.

I ended up with the following, which does a couple of other things. If you give the script no arguments, it displays a list of all .rb files in the search path. For any modules after a “-e” it invokes gvim (replace by your editor of choice).

That does everything I need for now.

Thanks to both you and Assaph for the help!

···

def which(libname)
$:.each do |d|
f = File.join(d, libname)
f += “.rb”
return f if File.exists? f
end

nil
end

def list_modules

Find all the .rb files

modules = {}

$:.each do |d|
Dir[d + "/.rb"].each do |path|
base = path.sub(/.
//, “”).sub(/.rb/, “”)
modules[base] = path
end
end

Display them, sorted by module name

maxWidth = 0

modules.keys.each do |mod|
length = mod.length

if length > maxWidth
  maxWidth = length
end

end

modules.keys.sort.each do |mod|
printf “%-*s %s\n”, maxWidth, mod, modules[mod]
end
end

if ARGV.length == 0
list_modules
else
edit = false

ARGV.each do |mod|
if mod == “-e”
edit = true
else
if (path = which mod).nil?
puts “Can’t find module ‘#{mod}’”
else
if edit
system “gvim #{path}”
else
puts path
end
end
end
end
end

Simon Strandgaard wrote:

Is there an easy way to discover the path to a “require”-ed module (assuming it’s a .rb file)?

You may want to look at rextra… I found this

def required
result =
$".each do |file|
$:.each do |path|
if File.exists?( path + ‘/’ + file )
result << (path + ‘/’ + file)
next
end
end
end
result
end

Btw, this is not really reliable (i.e. always correct) right? Since $:
might have been manipulated in between. Also the code above did not
check the case when a file is required by absolute path.

To be more reliable, perhaps extend Kernel::require. Or always require
with absolute path (but that’s un-Rubic).

···


dave

David Garamond wrote:

Btw, this is not really reliable (i.e. always correct) right? Since $:
might have been manipulated in between. Also the code above did not
check the case when a file is required by absolute path.

True.

Fortunately, for my purpose, it was perfect. I was really more interested in being able to find the source code to a given library module.

Of course, given what you say, very occasionally, I won’t be looking at the right piece of code, but I can live with that :-).

Cheers,