ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
J'essaie simplement d'accéder à un fichier .rb depuis le répertoire some et un tutoriel me dit d'utiliser ce code mais je ne vois pas comment il trouve le fichier gem.
ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
J'essaie simplement d'accéder à un fichier .rb depuis le répertoire some et un tutoriel me dit d'utiliser ce code mais je ne vois pas comment il trouve le fichier gem.
File.expand_path('../../Gemfile', __FILE__)
est un idiome Ruby quelque peu laid pour obtenir le chemin absolu d'un fichier lorsque vous connaissez le chemin relatif au fichier actuel. Une autre façon de l'écrire est la suivante :
File.expand_path('../Gemfile', File.dirname(__FILE__))
Les deux sont moches, mais la première variante est plus courte. Cependant, la première variante est également très peu intuitive, jusqu'à ce que l'on s'y habitue. Pourquoi le supplément ..
? (mais la deuxième variante peut donner une idée de la raison pour laquelle elle est nécessaire).
Voici comment cela fonctionne : File.expand_path
renvoie le chemin absolu du premier argument, relatif au deuxième argument (qui est par défaut le répertoire de travail actuel). __FILE__
est le chemin d'accès au fichier dans lequel se trouve le code. Puisque le deuxième argument dans ce cas est un chemin vers un fichier, et que File.expand_path
suppose un répertoire, nous devons coller un supplément de ..
dans le chemin pour obtenir le bon chemin. Voici comment cela fonctionne :
File.expand_path
est implémenté de la manière suivante (dans le code suivant) path
aura la valeur de ../../Gemfile
y relative_to
aura la valeur 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
(il y a un peu plus que ça, ça s'étend ~
dans le répertoire personnel et ainsi de suite -- il y a probablement d'autres problèmes avec le code ci-dessus)
En passant par un appel au code ci-dessus absolute_path
obtiendra d'abord la valeur /path/to/file.rb/../../Gemfile
puis, pour chaque tour de la boucle, le premier ..
sera supprimé, ainsi que le composant de chemin qui le précède. Premier site /file.rb/..
est retiré, puis au tour suivant /to/..
est supprimé, et nous obtenons /path/Gemfile
.
Pour faire une longue histoire courte, File.expand_path('../../Gemfile', __FILE__)
est une astuce pour obtenir le chemin absolu d'un fichier lorsque vous connaissez le chemin relatif au fichier actuel. L'extra ..
dans le chemin d'accès relatif est d'éliminer le nom du fichier en __FILE__
.
Dans Ruby 2.0, il existe un Kernel
fonction appelée __dir__
qui est mis en œuvre comme File.dirname(File.realpath(__FILE__))
.
Y a-t-il une raison pour laquelle vous ne pouvez pas simplement utiliser "require_relative", si ce n'est l'incompatibilité avec la version 1.9.2 de Ruby ?
Deux références :
Je suis tombée sur ça aujourd'hui :
boot.rb commit dans le Github Rails
Si vous montez de deux répertoires à partir de boot.rb dans l'arborescence des répertoires :
/railties/lib/rails/générateurs/rails/app/templates
vous voyez Gemfile, ce qui me pousse à croire que File.expand_path("../../Gemfile", __FILE__)
référence le fichier suivant : /path/to/this/file/../../Gemfile
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
2 votes
Voir aussi la question stackoverflow.com/questions/4333286