patternrubyMinor
Return path to rubygems.rb
Viewed 0 times
returnrubygemspath
Problem
From the command line, I can easily find the path to
and from a Ruby script I can also do this
However is a simpler way available to do this, for example without using
Update from posted answer
Update from posted comment
rubygems.rb$ gem which rubygems
/usr/lib/ruby/1.9.1/rubygems.rband from a Ruby script I can also do this
require 'rubygems/commands/which_command'
wc = Gem::Commands::WhichCommand.new
puts wc.find_paths 'rubygems', $LOAD_PATHHowever is a simpler way available to do this, for example without using
require 'rubygems/commands/which_command', and without a system() call?Update from posted answer
puts $".grep(/rubygems.rb/).firstUpdate from posted comment
puts Gem.method(:dir).source_location.firstSolution
Whether a simpler solution exists depends on what your motivation is.
Let's look inside the implementation of
That's the code you need. If there were a simpler way,
However, there is a way to cheat:
require(name) → true or false
Loads the given
the feature is already loaded.
If the filename does not resolve to an absolute path, it will be
searched for in the directories listed in
If the filename has the extension “.rb”, it is loaded as a source
file; if the extension is “.so”, “.o”, or “.dll”, or the default
shared library extension on the current platform, Ruby loads the
shared library as a Ruby extension. Otherwise, Ruby tries adding
“.rb”, “.so”, and so on to the name until found. If the file named
cannot be found, a
For Ruby extensions the filename given may use any shared library
extension. For example, on Linux the socket extension is “socket.so”
and
The absolute path of the loaded file is added to
(
again.
Or, it might be more accurate to say that
Therefore, if you are willing to let Ruby actually load the file first, then you could ask Ruby after the fact:
Let's look inside the implementation of
Gem::Commands::WhichCommand#find_paths.def find_paths(package_name, dirs)
result = []
dirs.each do |dir|
Gem.suffixes.each do |ext|
full_path = File.join dir, "#{package_name}#{ext}"
if File.exist? full_path and not File.directory? full_path then
result << full_path
return result unless options[:show_all]
end
end
end
result
endThat's the code you need. If there were a simpler way,
find_paths would have used it.However, there is a way to cheat:
Kernel#require needs to do a very similar thing when it actually tries to load a module:require(name) → true or false
Loads the given
name, returning true if successful and false ifthe feature is already loaded.
If the filename does not resolve to an absolute path, it will be
searched for in the directories listed in
$LOAD_PATH ($:).If the filename has the extension “.rb”, it is loaded as a source
file; if the extension is “.so”, “.o”, or “.dll”, or the default
shared library extension on the current platform, Ruby loads the
shared library as a Ruby extension. Otherwise, Ruby tries adding
“.rb”, “.so”, and so on to the name until found. If the file named
cannot be found, a
LoadError will be raised.For Ruby extensions the filename given may use any shared library
extension. For example, on Linux the socket extension is “socket.so”
and
require 'socket.dll' will load the socket extension.The absolute path of the loaded file is added to
$LOADED_FEATURES(
$"). A file will not be loaded again if its path already appears in$". For example, require 'a'; require './a' will not load a.rbagain.
Or, it might be more accurate to say that
find_paths simulates what require would do.Therefore, if you are willing to let Ruby actually load the file first, then you could ask Ruby after the fact:
require 'rubygems'
$LOADED_FEATURES.grep /\/rubygems\./Code Snippets
def find_paths(package_name, dirs)
result = []
dirs.each do |dir|
Gem.suffixes.each do |ext|
full_path = File.join dir, "#{package_name}#{ext}"
if File.exist? full_path and not File.directory? full_path then
result << full_path
return result unless options[:show_all]
end
end
end
result
endrequire 'rubygems'
$LOADED_FEATURES.grep /\/rubygems\./Context
StackExchange Code Review Q#48200, answer score: 3
Revisions (0)
No revisions yet.