ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
Sto solo cercando di accedere a un file .rb dalla directory some e un tutorial mi dice di usare questo codice ma non vedo come sta trovando il file gem.
ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
Sto solo cercando di accedere a un file .rb dalla directory some e un tutorial mi dice di usare questo codice ma non vedo come sta trovando il file gem.
Risposte:
File.expand_path('../../Gemfile', __FILE__)
è un idioma Ruby un po 'brutto per ottenere il percorso assoluto di un file quando si conosce il percorso relativo al file corrente. Un altro modo per scriverlo è questo:
File.expand_path('../Gemfile', File.dirname(__FILE__))
entrambi sono brutti, ma la prima variante è più corta. La prima variante è, tuttavia, anche molto non intuitiva finché non ci si prende la mano. Perché l'extra ..? (ma la seconda variante può dare un indizio sul motivo per cui è necessaria).
Funziona così: File.expand_pathrestituisce il percorso assoluto del primo argomento, relativo al secondo argomento (che per impostazione predefinita è la directory di lavoro corrente). __FILE__è il percorso del file in cui si trova il codice. Poiché il secondo argomento in questo caso è un percorso di un file e File.expand_pathpresuppone una directory, dobbiamo inserire un extra ..nel percorso per ottenere il percorso corretto. È così che funziona:
File.expand_pathè fondamentalmente implementato in questo modo (nel codice seguente pathavrà il valore di ../../Gemfilee relative_toavrà il valore di /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
(c'è qualcosa in più, si espande ~nella directory home e così via - probabilmente ci sono anche altri problemi con il codice sopra)
Passando attraverso una chiamata al codice sopra absolute_pathsi otterrà prima il valore /path/to/file.rb/../../Gemfile, quindi per ogni round nel ciclo il primo ..verrà rimosso, insieme al componente percorso prima di esso. Il primo /file.rb/..viene rimosso, quindi il round successivo /to/..viene rimosso e otteniamo /path/Gemfile.
Per farla breve, File.expand_path('../../Gemfile', __FILE__)è un trucco per ottenere il percorso assoluto di un file quando si conosce il percorso relativo al file corrente. L'extra ..nel percorso relativo è eliminare il nome del file in __FILE__.
In Ruby 2.0 c'è una Kernelfunzione chiamata __dir__che è implementata come File.dirname(File.realpath(__FILE__)).
File.expand_path('../Gemfile',__dir__)
File.expand_path assumes a directory, anche se __FILE__non è una directory. Affinché le cose abbiano un senso usa __dir__che in realtà è una directory.
Due riferimenti:
Mi sono imbattuto in questo oggi:
boot.rb commit in Rails Github
Se salite due directory da boot.rb nell'albero delle directory:
/ railties / lib / rails / generators / rails / app / templates
vedi Gemfile, il che mi porta a crederci File.expand_path("../../Gemfile", __FILE__) riferimento al seguente file:/path/to/this/file/../../Gemfile