File.expand_path ("../../Gemfile", __FILE__) How does it work? Where is the file located?

ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)

I'm just trying to access the .rb file from some directory, and the tutorial tells me to use this code, but I don’t see how it finds the gem file.

+71
ruby
Dec 17 '10 at 21:31
source share
2 answers
 File.expand_path('../../Gemfile', __FILE__) 

- A somewhat ugly Ruby idiom for getting an absolute file path when you know the path to the current file. Another way to write this:

 File.expand_path('../Gemfile', File.dirname(__FILE__)) 

both are ugly, but the first option is shorter. The first option, however, is also very unintuitive until you hang it. Why extra .. ? (but the second option may give an idea of ​​why this is necessary).

Here's how it works: File.expand_path returns the absolute path of the first argument relative to the second argument (which by default refers to the current working directory). __FILE__ is the path to the file where the code is located. Since the second argument in this case is the path to the file, and File.expand_path takes the directory, we must insert an additional .. in the path to get the path to the right. Here's how it works:

File.expand_path is mainly implemented as follows (in the following code, path will have the value ../../Gemfile and relative_to will have the value /path/to/file.rb ):

 def File.expand_path(path, relative_to=Dir.getwd) # first the two arguments are concatenated, with the second argument first absolute_path = File.join(relative_to, path) while absolute_path.include?('..') # remove the first occurrence of /<something>/.. absolute_path = absolute_path.sub(%r{/[^/]+/\.\.}, '') end absolute_path end 

(there is a bit more, it extends ~ to the home directory, etc. - there are probably other problems with the code above)

When calling the code above absolute_path , first get the value /path/to/file.rb/../../Gemfile , then the first .. for each round in the loop will be deleted .. along with the path component in front of it. First /file.rb/.. is deleted, then in the next round /to/.. is deleted, and we get /path/Gemfile .

In short, File.expand_path('../../Gemfile', __FILE__) is a trick to get the absolute path to the file when you know the path to the current file. An optional .. in the relative path is to exclude the file name in __FILE__ .

+166
Dec 18 '10 at 20:11
source share

Two links:

I came across this today:

boot.rb commit in Rails Github

If you run two directories from boot.rb in the directory tree:

/ railties / lib / rails / generators / rails / app / templates

you see a Gemfile, which makes me think that File.expand_path("../../Gemfile", __FILE__) refers to the following file: /path/to/this/file/../../Gemfile

+8
Dec 17 '10 at 21:57
source share



All Articles