ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
Solo estoy tratando de acceder a un archivo .rb desde el directorio some y un tutorial me dice que use este código, pero no veo cómo está encontrando el archivo gem.
ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
Solo estoy tratando de acceder a un archivo .rb desde el directorio some y un tutorial me dice que use este código, pero no veo cómo está encontrando el archivo gem.
Respuestas:
File.expand_path('../../Gemfile', __FILE__)
es un modismo de Ruby algo feo para obtener la ruta absoluta a un archivo cuando conoce la ruta relativa al archivo actual. Otra forma de escribirlo es esta:
File.expand_path('../Gemfile', File.dirname(__FILE__))
ambos son feos, pero la primera variante es más corta. Sin embargo, la primera variante tampoco es muy intuitiva hasta que la domines. ¿Por qué el extra ..
? (pero la segunda variante puede dar una pista de por qué se necesita).
Así es como funciona: File.expand_path
devuelve la ruta absoluta del primer argumento, en relación con el segundo argumento (que por defecto es el directorio de trabajo actual). __FILE__
es la ruta al archivo en el que se encuentra el código. Dado que el segundo argumento en este caso es una ruta a un archivo, y File.expand_path
asume un directorio, tenemos que colocar un extra ..
en la ruta para obtener la ruta correcta. Así es como funciona:
File.expand_path
se implementa básicamente así (en el siguiente código path
tendrá el valor de ../../Gemfile
y relative_to
tendrá el valor de /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
(hay un poco más, se expande ~
al directorio de inicio y así sucesivamente; probablemente también haya otros problemas con el código anterior)
Al realizar una llamada al código anterior absolute_path
, primero obtendrá el valor /path/to/file.rb/../../Gemfile
, luego, para cada ronda del ciclo ..
, se eliminará la primera , junto con el componente de ruta anterior. Primero /file.rb/..
se elimina, luego en la siguiente ronda /to/..
se elimina y obtenemos /path/Gemfile
.
En resumidas cuentas, File.expand_path('../../Gemfile', __FILE__)
es un truco obtener la ruta absoluta de un archivo cuando se conoce la ruta relativa al archivo actual. El extra ..
en la ruta relativa es eliminar el nombre del archivo en formato __FILE__
.
En Ruby 2.0 hay una Kernel
función llamada __dir__
que se implementa como File.dirname(File.realpath(__FILE__))
.
File.expand_path('../Gemfile',__dir__)
File.expand_path assumes a directory
, aunque __FILE__
no es un directorio. Para que las cosas tengan sentido, use __dir__
que en realidad es un directorio.
Dos referencias:
Me encontré con esto hoy:
boot.rb confirmado en Rails Github
Si sube dos directorios desde boot.rb en el árbol de directorios:
/ railties / lib / rails / generators / rails / app / templates
ves Gemfile, lo que me lleva a creer que hace File.expand_path("../../Gemfile", __FILE__)
referencia al siguiente archivo:/path/to/this/file/../../Gemfile