What's the equivalent of python's __file__ in ruby?
开发者_开发百科In python after imports, one can see the file, that has been loaded/where the module comes from.
>>> import os
>>> os.__file__
'/Users/tm/lib/python2.6/os.pyc'
What would be the equivalent in ruby?
>> require 'xmlrpc/client'
=> true
>> ...
There's nothing exactly equivalent.
All files that have been required
are listed in $LOADED_FEATURES
in the order they were require
d. So, if you want to know where a file came from directly after it was require
d, you simply need to look at the end:
$LOADED_FEATURES.last if require 'yaml'
# => 'C:/Program Files/Ruby/lib/ruby/1.9.1/yaml.rb'
However, unless you record every call to require
it's going to be hard to figure out which entry corresponds to which call. Also, if a file is already in $LOADED_FEATURES
, it will not get loaded again:
require 'yaml'
# => true
# true means: the file was loaded
$LOADED_FEATURES.last
# => 'C:/Program Files/Ruby/lib/ruby/1.9.1/yaml.rb'
require 'json'
$LOADED_FEATURES.last
# => 'C:/Program Files/Ruby/lib/ruby/1.9.1/json.rb'
require 'yaml'
# => false
# false means: the file wasn't loaded again, because it has already been loaded
$LOADED_FEATURES.last
# => 'C:/Program Files/Ruby/lib/ruby/1.9.1/json.rb'
# Last loaded feature is still JSON, because YAML wasn't actually loaded twice
Also, many libraries aren't contained in a single file. So, the require
d files might themselves contain calls to require
. In my case, for example, require 'yaml'
not only loads yaml.rb
but a whole bunch of files (15 to be exact):
C:/Program Files/Ruby/lib/ruby/1.9.1/i386-mingw32/stringio.so
C:/Program Files/Ruby/lib/ruby/1.9.1/i386-mingw32/syck.so
C:/Program Files/Ruby/lib/ruby/1.9.1/syck/error.rb
C:/Program Files/Ruby/lib/ruby/1.9.1/syck/basenode.rb
C:/Program Files/Ruby/lib/ruby/1.9.1/syck/syck.rb
C:/Program Files/Ruby/lib/ruby/1.9.1/syck/tag.rb
C:/Program Files/Ruby/lib/ruby/1.9.1/syck/stream.rb
C:/Program Files/Ruby/lib/ruby/1.9.1/syck/constants.rb
C:/Program Files/Ruby/lib/ruby/1.9.1/date/format.rb
C:/Program Files/Ruby/lib/ruby/1.9.1/date.rb
C:/Program Files/Ruby/lib/ruby/1.9.1/syck/rubytypes.rb
C:/Program Files/Ruby/lib/ruby/1.9.1/syck/types.rb
C:/Program Files/Ruby/lib/ruby/1.9.1/yaml/syck.rb
C:/Program Files/Ruby/lib/ruby/1.9.1/syck.rb
C:/Program Files/Ruby/lib/ruby/1.9.1/yaml.rb
Assuming you are using rubygems, you can find out which file it loads by using Gem.find_files(file)
.
e.g.:
>> puts Gem.find_files('active_record')
/Library/Ruby/Gems/1.8/gems/activerecord-3.0.0.beta2/lib/active_record.rb
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record.rb
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record.rb
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record.rb
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record.rb
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.6/lib/active_record.rb
The first element of the array will be the file that is loaded by require 'active_record'
.
Another way to find out which file is loaded by require, would be to call $ gem which foo
from the command line.
There's nothing that's an exact match. It's easy to find it yourself, though:
# Find where a path `p` was loaded from.
def locate(p)
# Find the first path in your load-paths that contains a file matching `p`.
$:.find { |l|
File.exists?(File.join(l, p))
}
end
ruby-1.9.1-p378 > locate('yaml')
=> "/home/johnf/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1"
# --> This tells you that 'yaml.rb' was loaded from here.
ruby-1.9.1-p378 > locate('zzz')
=> nil
# --> There's no matches for this library.
ruby-1.9.1-p378 > locate('haml')
=> "/home/johnf/.rvm/gems/ruby-1.9.1-p378@standard/gems/haml-3.0.12/bin"
# --> Here's a third-party library from my gems.
精彩评论