ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
Sadece bir dizinden bir .rb dosyasına erişmeye çalışıyorum ve bir eğitim bana bu kodu kullanmamı söylüyor, ancak gem dosyasını nasıl bulduğunu anlamıyorum.
Yanıtlar:
File.expand_path('../../Gemfile', __FILE__)
mevcut dosyaya göre yolu bildiğinizde bir dosyanın mutlak yolunu elde etmek için biraz çirkin bir Ruby deyimidir. Bunu yazmanın başka bir yolu da şudur:
File.expand_path('../Gemfile', File.dirname(__FILE__))
ikisi de çirkin ama ilk varyant daha kısa. Bununla birlikte, ilk varyant, siz onu asana kadar çok sezgisel değildir. Neden fazlalık ..? (ancak ikinci değişken, neden gerekli olduğuna dair bir ipucu verebilir).
İşleyiş şekli şöyledir: File.expand_pathikinci bağımsız değişkene göre ilk bağımsız değişkenin mutlak yolunu döndürür (varsayılan olarak geçerli çalışma dizinidir). __FILE__kodun bulunduğu dosyanın yoludur. Bu durumda ikinci argüman bir dosyaya giden bir yol olduğundan ve File.expand_pathbir dizin varsaydığından .., yolu doğru almak için yola fazladan bir tane yapıştırmalıyız . Bu nasıl çalışır:
File.expand_pathTemelde (Aşağıdaki kodda böyle uygulanmaktadır pathdeğerini sahip olacak ../../Gemfileve relative_todeğerini sahip olacaktır /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
(biraz daha fazlası var, ~ana dizine genişliyor ve benzeri - muhtemelen yukarıdaki kodla ilgili başka sorunlar da var)
Yukarıdaki koda yapılan bir çağrıda ilerlemek absolute_pathönce değeri alır /path/to/file.rb/../../Gemfile, ardından döngüdeki her tur için ilki .., ondan önceki yol bileşeni ile birlikte kaldırılır. Önce /file.rb/..kaldırılır, sonra bir sonraki turda /to/..kaldırılır ve alırız /path/Gemfile.
Uzun lafın kısası, File.expand_path('../../Gemfile', __FILE__)mevcut dosyaya göre yolu bildiğinizde bir dosyanın mutlak yolunu elde etmek için bir hiledir. ..Göreceli yoldaki fazlalık , içindeki dosyanın adını ortadan kaldırmaktır __FILE__.
Ruby 2.0 bir hayır vardır Kerneldenir fonksiyon __dir__olarak uygulanır File.dirname(File.realpath(__FILE__)).
File.expand_path('../Gemfile',__dir__)
File.expand_path assumes a directoryolmasa __FILE__da nihayet benim için tıkladı. Şeylerin mantıklı olması için, __dir__hangisinin aslında bir dizin olduğunu kullanın.
İki referans:
Bugün buna rastladım:
Rails Github'da boot.rb commit
Dizin ağacındaki boot.rb'den iki dizin yukarı çıkarsanız:
/ railties / lib / rails / jeneratörler / rails / app / templates
Gemfile'ı görüyorsunuz, bu da beni File.expand_path("../../Gemfile", __FILE__)dosyanın aşağıdaki referanslara inanmasına neden oluyor :/path/to/this/file/../../Gemfile