File.expand_path('../../Gemfile', __FILE__)
это несколько уродливая идиома Ruby для получения абсолютного пути к файлу, когда вы знаете путь относительно текущего файла. Другой способ записать это:
File.expand_path('../Gemfile', File.dirname(__FILE__))
оба уродливы, но первый вариант короче. Однако первый вариант также очень неинтуитивен, пока вы не освоите его. Почему лишнее ..? (но второй вариант может подсказать, зачем он нужен).
Вот как это работает: File.expand_pathвозвращает абсолютный путь первого аргумента относительно второго аргумента (который по умолчанию соответствует текущему рабочему каталогу). __FILE__- это путь к файлу, в котором находится код. Поскольку второй аргумент в этом случае - это путь к файлу и File.expand_pathпредполагает наличие каталога, мы должны добавить в путь дополнительный аргумент, ..чтобы получить правильный путь. Вот как это работает:
File.expand_pathв основном реализован следующим образом (в следующем коде pathбудет иметь значение ../../Gemfileи relative_toбудет иметь значение /path/to/file.rb):
def File.expand_path(path, relative_to=Dir.getwd)
absolute_path = File.join(relative_to, path)
while absolute_path.include?('..')
absolute_path = absolute_path.sub(%r{/[^/]+/\.\.}, '')
end
absolute_path
end
(есть ~еще кое- что, он расширяется до домашнего каталога и так далее - вероятно, есть и другие проблемы с приведенным выше кодом)
При пошаговом вызове приведенного выше кода absolute_pathсначала будет получено значение /path/to/file.rb/../../Gemfile, затем для каждого раунда в цикле первый ..будет удален вместе с компонентом пути перед ним. Сначала /file.rb/..снимается, потом на следующем раунде /to/..снимается, и мы получаем /path/Gemfile.
Короче говоря, File.expand_path('../../Gemfile', __FILE__)это уловка, позволяющая получить абсолютный путь к файлу, когда вы знаете путь относительно текущего файла. Дополнительное значение ..в относительном пути - исключить имя файла в __FILE__.
В Ruby 2.0 есть Kernelфункция, __dir__которая реализована как File.dirname(File.realpath(__FILE__)).