Quelle est la différence entre require_relative
et require
en Ruby?
Il suffit de regarder le docs :
require_relative
complète la méthode intégréerequire
en vous permettant de charger un fichier relatif au fichier contenant l'instructionrequire_relative
.Par exemple, si vous avez des classes de tests unitaires dans le répertoire "test" et des données les concernant dans le répertoire test "test/data", vous pouvez utiliser une ligne comme celle-ci dans un scénario de test:
require_relative "data/customer_data_1"
require_relative
_ EST UN SOUS-ENSEMBLE PRATIQUE DE require
_require_relative('path')
_
équivaut à:
_require(File.expand_path('path', File.dirname(__FILE__)))
_
si ___FILE__
_ est défini, ou sinon LoadError
est généré.
Ceci implique que:
_require_relative 'a'
_ et _require_relative './a'
_ require par rapport à fichier actuel (___FILE__
_).
C’est ce que vous voulez utiliser lorsque vous en avez besoin dans votre bibliothèque, car 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
car ___FILE__
_ n'est pas défini dans 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'
_ requiert par rapport à 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 chemin actuel.
Ceci n’est pas possible avec _require_relative
_ car la documentation dit que la recherche de chemin ne se produit que lorsque "le nom du fichier ne se résout pas en chemin absolu" (c’est-à-dire qu'il commence par _/
_ ou _./
_ ou _../
_), ce qui est toujours le cas pour _File.expand_path
_.
L'opération suivante est possible avec les deux, mais vous voudrez utiliser require
car elle est plus courte et plus efficace:
require '/a.rb'
_ et _require_relative '/a.rb'
_ requièrent tous deux le chemin absolu.Lecture du source
Lorsque les documents ne sont pas clairs, je vous recommande de jeter un coup d'œil aux sources (bascule source dans les documents). Dans certains cas, il est utile de comprendre ce qui se passe.
exiger:
_VALUE rb_f_require(VALUE obj, VALUE fname) {
return rb_require_safe(fname, rb_safe_level());
}
_
require_relative:
_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 le même 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__
_
De Ruby API :
require_relative complète la méthode intégrée require en vous permettant de charger un fichier relatif au fichier contenant l'instruction require_relative.
Lorsque vous utilisez require pour charger un fichier, vous accédez généralement à une fonctionnalité correctement installée et rendue accessible sur votre système. require n’offre pas une bonne solution pour charger des fichiers dans le code du projet. Cela peut être utile lors d'une phase de développement, pour accéder aux données de test ou même pour accéder à des fichiers "bloqués" dans un projet, non destiné à être utilisé à l'extérieur.
Par exemple, si vous avez des classes de tests unitaires dans le répertoire "test" et des données les concernant dans le répertoire test "test/data", vous pouvez utiliser une ligne comme celle-ci dans un scénario de test:
require_relative "data/customer_data_1"
Etant donné que ni "test" ni "test/données" ne sont vraisemblablement dans le chemin de la bibliothèque de Ruby (et pour de bonnes raisons), une exigence normale ne les trouvera pas. require_relative est une bonne solution à ce problème particulier.
Vous pouvez inclure ou omettre l’extension (.rb ou .so) du fichier que vous chargez.
chemin doit répondre à to_str.
Vous pouvez trouver la documentation sur http://extensions.rubyforge.org/rdoc/classes/Kernel.html
require
pour les gemmes installéesrequire_relative
_ pour les fichiers locauxrequire
utilise votre $LOAD_PATH
pour rechercher les fichiers.
_require_relative
_ utilise l'emplacement actuel du fichier à l'aide de l'instruction
Require suppose que vous ayez installé (par exemple _gem install [package]
_) un package quelque part sur votre système pour cette fonctionnalité.
Lorsque vous utilisez require
, vous pouvez utiliser le format "_./
_" pour un fichier du répertoire actuel, par exemple. _require "./my_file"
_ mais ce n'est pas une pratique courante ou recommandée et vous devriez utiliser _require_relative
_ à la place.
Cela signifie simplement inclure le fichier "par rapport à l'emplacement du fichier avec l'instruction require_relative". Je recommande généralement que les fichiers se trouvent "dans" l'arborescence de répertoires actuelle, par opposition à "en haut", par exemple. ne 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ément" dans une arborescence de répertoires, il peut être nécessaire de "monter et descendre" une autre branche d'arborescence. Plus simplement peut-être, n'utilisez pas require_relative pour les fichiers situés en dehors de ce référentiel (en supposant que vous utilisez git, qui est en grande partie un standard de facto à ce stade, fin 2018).
Notez que _require_relative
_ utilise le répertoire en cours du fichier avec l'instruction require_relative (le répertoire actuel dans lequel vous utilisez la commande n'est donc pas nécessairement obligatoire). ). Ceci garde le chemin _require_relative
_ "stable", car il est toujours relatif au fichier le nécessitant de la même manière.
Les premières réponses sont correctes, mais profondément techniques. Pour ceux plus récents au Ruby--
require_relative
sera probablement utilisé pour importer le code 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 que vous souhaitez les inclure dans ~/my-project/solution.rb
? dans solution.rb
vous ajouteriez require_relative 'data'
.
il est important de noter que ces fichiers n'ont pas besoin d'être dans le même répertoire. require_relative '../../folder1/folder2/data'
est également valide.
require
sera très probablement utilisé pour importer le code d'une bibliothèque écrite par quelqu'un d'autre.par exemple, si vous souhaitez utiliser l'une des fonctions d'assistance fournies dans la bibliothèque active_support
? vous devez installer la gemme avec gem install activesupport
puis dans le fichier require 'active_support'
.
require 'active_support/all'
"FooBar".underscore
Dit différemment--
require_relative
nécessite un fichier spécifiquement désigné par rapport au fichier qui l'appelle.
require
nécessite un fichier inclus dans $ LOAD_PATH.
Je viens de voir que le code de RSpec contient des commentaires sur require_relative
étant O(1) constante et require
étant O(N) linéaire. Donc, probablement la différence est que require_relative
est le préféré par rapport à require
.
Je souhaite ajouter que, lorsque vous utilisez Windows, vous pouvez utiliser require './1.rb'
si le script est exécuté en local ou à partir d'un lecteur réseau mappé, mais lorsqu'il est exécuté à partir d'un chemin UNC\nom_serveur\nom_du_nom \, vous devez utiliser require_relative './1.rb'
. Je ne me mêle pas à la discussion pour l'utiliser pour d'autres raisons.