327 votes

Quelle est la différence entre require_relative et require en Ruby ?

Quelle est la différence entre require_relative y require en Ruby ?

9 votes

Avant la version 1.9.2, il n'y avait pas besoin de require_relative, car le répertoire courant de script était dans $: . Voir stackoverflow.com/questions/2900370

1 votes

Require_relative requiert un fichier spécifiquement pointé par rapport au fichier qui l'appelle. require requiert un fichier inclus dans le $LOAD_PATH.

318voto

miku Points 63392

Il suffit de regarder le docs :

require_relative complète la méthode intégrée require en vous permettant de charger un fichier qui est relatif au fichier contenant l'adresse IP. require_relative déclaration.

Par exemple, si vous avez des classes de tests unitaires dans le répertoire "test" et des données pour celles-ci dans le répertoire "test/data", vous pouvez utiliser une ligne comme celle-ci dans un scénario de test :

require_relative "data/customer_data_1"

32 votes

Y a-t-il une différence entre require './file.rb' y require_relative 'file.rb' ?

76 votes

@CiroSantilli Oui. require_relative vous permet de "charger un fichier qui est relatif au fichier contenant le require_relative déclaration ". Avec require , ./ indique un chemin relatif à votre répertoire de travail actuel.

19 votes

Je pense qu'il est plus important de noter que require str cherchera toujours dans les répertoires de $LOAD_PATH. Vous devez utiliser require_relative lorsque le fichier que vous devez charger existe quelque part par rapport au fichier qui demande le chargement. Réserve require pour les dépendances "externes".

111voto

Ciro Santilli Points 3341

require_relative est un sous-ensemble commode de require

require_relative('path')

égaux :

require(File.expand_path('path', File.dirname(__FILE__)))

si __FILE__ est définie, ou elle soulève LoadError autrement.

Cela implique que :

  • require_relative 'a' y require_relative './a' exiger par rapport à la fichier actuel ( __FILE__ ).

    C'est ce que vous voulez utiliser lorsque vous demandez à l'intérieur de votre bibliothèque, puisque vous ne voulez pas que le résultat dépende du répertoire actuel de l'appelant.

  • eval('require_relative("a.rb")') soulève LoadError porque __FILE__ n'est pas défini à l'intérieur de eval .

    C'est pourquoi vous ne pouvez pas utiliser require_relative dans les tests RSpec, qui obtiennent eval ed.

Les opérations suivantes ne sont possibles qu'avec require :

  • require './a.rb' exige par rapport à la répertoire actuel

  • require 'a.rb' utilise le chemin de recherche ( $LOAD_PATH ) à exiger. Il ne trouve pas les fichiers relatifs au répertoire ou au chemin actuel.

    Cela n'est pas possible avec require_relative parce que la documentation indique que la recherche de chemin ne se fait que lorsque "le nom de fichier ne correspond pas à un chemin absolu" (c'est-à-dire qu'il commence par / o ./ o ../ ), ce qui est toujours le cas pour File.expand_path .

L'opération suivante est possible avec les deux, mais vous voudrez utiliser la fonction require car elle est plus courte et plus efficace :

  • require '/a.rb' y require_relative '/a.rb' Les deux requièrent le chemin absolu.

Lire la source

Lorsque la documentation n'est pas claire, je vous recommande de jeter un coup d'œil aux sources (basculer la source dans la documentation). Dans certains cas, cela aide à comprendre ce qui se passe.

exiger :

VALUE rb_f_require(VALUE obj, VALUE fname) {
  return rb_require_safe(fname, rb_safe_level());
}

exiger_relatif :

VALUE rb_f_require_relative(VALUE obj, VALUE fname) {
    VALUE base = rb_current_realfilepath();
    if (NIL_P(base)) {
        rb_loaderror("cannot infer basepath");
    }
    base = rb_file_dirname(base);
    return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
}

Cela nous permet de conclure que

require_relative('path')

est la même chose que :

require(File.expand_path('path', File.dirname(__FILE__)))

parce que :

rb_file_absolute_path   =~ File.expand_path
rb_file_dirname1        =~ File.dirname
rb_current_realfilepath =~ __FILE__

83voto

Michael Durrant Points 30342

Résumé

Utilice require pour les gemmes installées

Utilice require_relative pour les fichiers locaux

require utilise votre $LOAD_PATH pour trouver les fichiers.
require_relative utilise l'emplacement actuel du fichier en utilisant l'instruction


exiger

Require repose sur le fait que vous avez installé (par ex. gem install [package] ) un paquet quelque part sur votre système pour cette fonctionnalité.

Lorsque vous utilisez require vous peut utiliser le " ./ "pour un fichier situé dans le répertoire courant, par ex. require "./my_file" mais ce n'est pas une pratique courante ou recommandée et vous devriez utiliser require_relative à la place.

exiger_relatif

Cela signifie simplement inclure le fichier "relativement à l'emplacement du fichier avec l'instruction require_relative". I généralement recommandent que les fichiers se trouvent "à l'intérieur" de l'arborescence du répertoire courant plutôt que "vers le haut", par exemple Ne le fais pas. utiliser

require_relative '../../../filename'

(jusqu'à 3 niveaux de répertoire) dans le système de fichiers car cela tend à créer des dépendances inutiles et fragiles. Cependant, dans certains cas, si vous êtes déjà "profond" dans une arborescence de répertoires, il peut être nécessaire de "monter et descendre" une autre branche de l'arborescence de répertoires. Plus simplement peut-être, ne pas utiliser require_relative pour les fichiers en dehors de ce référentiel (en supposant que vous utilisez git qui est largement une norme de-facto à ce stade, fin 2018).

Notez que require_relative utilise le répertoire courant du fichier avec le paramètre require_relative (donc pas nécessairement le répertoire actuel à partir duquel vous utilisez la commande). Cela permet de conserver le require_relative chemin "stable" car il sera toujours relatif au fichier qui le nécessite de la même manière.

77voto

svilenv Points 949

À partir de l'API Ruby :

require_relative complète le méthode builtin require en vous permettant de charger un fichier qui est relatif au fichier contenant l'état require_relative l'instruction require_relative.

Lorsque vous utilisez require pour charger un fichier, vous accédez généralement à fonctionnalité qui a été correctement correctement installée, et rendue accessible, dans votre système. require n'offre pas une bonne solution pour charger des fichiers dans le code du projet. Cela peut être utile pendant une phase de développement, pour accéder à des données de test, ou même pour accéder à des fichiers qui sont "enfermés" à l'intérieur à l'intérieur d'un projet, non destinés à l'extérieur.

Par exemple, si vous avez un test unitaire dans le répertoire "test", et des données pour elles dans le répertoire test "test/data", alors vous pourriez utiliser une ligne comme celle-ci dans un scénario de test :

require_relative "data/customer_data_1" 

Puisque ni "test" ni "test/data" ne sont susceptibles de dans le chemin de la bibliothèque de Ruby (et pour raison), un require normal ne les trouvera pas normal ne les trouvera pas. require_relative est une bonne solution pour ce problème particulier.

Vous pouvez inclure ou omettre l'extension (.rb ou .so) du fichier que vous chargez chargez.

Le chemin doit répondre à to_str.

Vous pouvez trouver la documentation à l'adresse suivante http://extensions.rubyforge.org/rdoc/classes/Kernel.html

45voto

common-nighthawk Points 369

Les premières réponses sont correctes, mais profondément techniques. Pour ceux qui découvrent Ruby :

  • require_relative sera très probablement utilisé pour introduire du code provenant d'un autre fichier que vous avez écrit.

par exemple, que se passe-t-il si vous avez des données dans ~/my-project/data.rb et vous voulez l'inclure dans ~/my-project/solution.rb ? dans solution.rb vous ajouteriez require_relative 'data' .

il est important de noter que ces fichiers ne doivent pas nécessairement se trouver dans le même répertoire. require_relative '../../folder1/folder2/data' est également valable.

  • require sera très probablement utilisé pour introduire du code provenant d'une bibliothèque écrite par quelqu'un d'autre.

par exemple, que se passe-t-il si vous voulez utiliser l'une des fonctions d'aide fournies dans le fichier active_support vous devrez installer la gemme avec gem install activesupport et ensuite dans le fichier require 'active_support' .

require 'active_support/all'
"FooBar".underscore

Dit autrement

  • require_relative nécessite un fichier spécifiquement pointé par rapport au fichier qui l'appelle.

  • require nécessite un fichier inclus dans le $LOAD_PATH .

Prograide.com

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.

Powered by:

X