2010-07-15 25 views
19

Donc, je suis en train d'écrire des tests rspec et je suis gêné par mon manque de compréhension Ruby.Ruby nécessite 'fichier' et l'emplacement relatif

J'ai une structure de fichier qui ressemble à ce qui suit:

  • GUI_Tests/Tests/test_spec.rb
  • GUI_Tests/windows_gui.rb
  • GUI_Tests/upload_tool.rb

lorsque j'exécute spec pour le fichier test_spec.rb, j'ai besoin que le fichier upload_tool soit inclus comme suit:

spec -r ../upload_tool -fs test_spec.rb 

Ensuite, le upload_tool nécessite windows_gui.rb, comme ceci:

require '../windows_gui' 

Ma question est, pourquoi donc je dois faire référence windows_gui.rb par rapport à test_spec.rb (nécessitant l'../) plutôt que le upload_tool.rb? Cela me semble faux, je vais vouloir utiliser le fichier upload_tool.rb hors contexte des spécifications du test, ce qui signifie qu'il faut changer chaque fois.

De toute évidence, il me manque quelque chose, mais si je ne référence pas par rapport à la spécification de test, je reçois un fichier introuvable erreur.

Désolé d'être si ignorant ici, mais je viens les mains vides. Toutes les pensées ont apprécié.

BB

+2

Ne vous sentez pas mal - je trouve que faire face à chemins relatifs l'une des choses les plus ennuyeuses à propos de ruby. Je l'ai énuméré dans [quelles sont les choses que vous aimeriez améliorer dans la langue ruby] (http://stackoverflow.com/questions/585457/what-are-the-things-you-would-like-improved-in -the-ruby-language/3261063 # 3261063) –

+0

Août 2012 - Notez que cet article a maintenant deux ans. La plupart des gens sont maintenant sur 1.9.2. Voir cet article http://stackoverflow.com/questions/9345412/relative-file-path-in-rspec aussi pour la meilleure solution (fév 2012) –

Répondre

20

Vous n'en avez pas. require s sont relatives au répertoire en cours, qui dans votre cas était GUI_Tests/Tests. Si vous avez fait ceci:

cd .. 
spec -r upload_tool -fs Test/test_spec.rb 

Vous devez utiliser ceci:

require 'windows_gui' # without '../' 

La façon la plus courante pour contourner ce problème utilise File.dirname(__FILE__):

require File.join(File.dirname(__FILE__), '..', 'windows_gui') 

REMARQUE: en Ruby 1.9.2 nécessite changé ses paramètres par défaut: Ruby: require vs require_relative - best practice to workaround running in both Ruby <1.9.2 and >=1.9.2

+1

Parfait - comme je l'ai dit, j'étais gêné de devoir même demander, mais Je suis content de l'avoir fait. Cela fait parfaitement sens. –

+19

En fait, 'require' est * not * par rapport au répertoire courant, il est relatif au * chemin de recherche * (c'est-à-dire la constante spéciale' $ LOAD_PATH' ou son alias '$:'). Il se trouve que sur les anciennes versions de Ruby (c'est-à-dire toutes sauf 1.9.2), le répertoire courant ('.') est dans le chemin de recherche par défaut:' p $ :. include ? ('.') # => true'. Cependant, à partir de Ruby 1.9.2 ce n'est plus le cas et ne devrait pas être invoqué. Dans Ruby 1.9, vous pouvez utiliser 'require_relative' qui fonctionne par rapport au fichier source à partir duquel il est appelé au lieu du chemin de recherche. –

+0

@Jorg: Mais si je cours ceci en 1.9: '$ :. replace []; require '../ somefile'', ça marche. – Adrian