Quelle est la différence entre require_relative
et require
en Ruby?
Quelle est la différence entre require_relative
et require
en Ruby?
Réponses:
Regardez les documents :
require_relative
complète la méthode intégréerequire
en vous permettant de charger un fichier relatif au fichier contenant l'require_relative
instruction.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 "test / data", vous pouvez utiliser une ligne comme celle-ci dans un scénario de test:
require_relative "data/customer_data_1"
require './file.rb'
et require_relative 'file.rb'
?
require_relative
vous permet de "charger un fichier relatif au fichier contenant l' require_relative
instruction ". Avec require
, ./
indique un chemin relatif à votre répertoire de travail actuel.
require str
recherche se fera 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 appelle le chargement. Réserve require
pour les dépendances "externes".
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 il soulèveLoadError
contraire.
Ceci implique que:
require_relative 'a'
et require_relative './a'
exiger par rapport au fichier actuel ( __FILE__
).
C'est ce que vous voulez utiliser lorsque vous avez besoin de l'intérieur de 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")')
lève LoadError
car __FILE__
n'est pas défini à l'intérieur eval
.
C'est pourquoi vous ne pouvez pas utiliser require_relative
dans les tests RSpec, qui sont eval
édités.
Les opérations suivantes ne sont possibles qu'avec require
:
require './a.rb'
requiert par rapport au répertoire courant
require 'a.rb'
utilise le chemin de recherche ( $LOAD_PATH
) pour exiger. Il ne trouve pas les fichiers relatifs au répertoire ou au chemin actuel.
Ce n'est pas possible avec require_relative
car les documents disent que la recherche de chemin ne se produit que lorsque "le nom de fichier ne se résout pas en un chemin absolu" (c'est-à-dire 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 l'utiliser require
car elle est plus courte et plus efficace:
require '/a.rb'
et les require_relative '/a.rb'
deux nécessitent le chemin absolu.Lire la source
Lorsque les documents ne sont pas clairs, je vous recommande de jeter un œil aux sources (basculer la source dans les documents). 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());
}
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__)))
car:
rb_file_absolute_path =~ File.expand_path
rb_file_dirname1 =~ File.dirname
rb_current_realfilepath =~ __FILE__
Depuis l'API Ruby :
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 à des fonctionnalités qui ont été correctement installées et rendues accessibles 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 "verrouillés" à l'intérieur d'un projet, non destinés à un usage extérieur.
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 "test / data", vous pouvez utiliser une ligne comme celle-ci dans un scénario de test:
require_relative "data/customer_data_1"
Comme ni "test" ni "test / data" ne sont susceptibles d'être dans le chemin d'accès à la bibliothèque de Ruby (et pour une bonne raison), une exigence normale 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.
le 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
Exiger repose sur le fait que vous avez installé (par exemple gem install [package]
) un package quelque part sur votre système pour cette fonctionnalité.
Lors de l'utilisation, require
vous pouvez utiliser le ./
format " " pour un fichier dans le répertoire courant, par exemple, require "./my_file"
mais ce n'est pas une pratique courante ou recommandée et vous devez utiliser à la require_relative
place.
Cela signifie simplement inclure le fichier «par rapport à l'emplacement du fichier avec l'instruction require_relative». Je généralement recommande que les fichiers doivent être « dans » l'arborescence du répertoire courant par opposition à « haut », par exemple , ne le font pas usage
require_relative '../../../filename'
(jusqu'à 3 niveaux de répertoire) dans le système de fichiers car cela a tendance à créer des dépendances inutiles et fragiles. Cependant, dans certains cas, si vous êtes déjà «profond» dans une arborescence de répertoires, une «branche d'arborescence de répertoires» peut être nécessaire. Plus simplement peut-être, n'utilisez pas require_relative pour les fichiers en dehors de ce référentiel (en supposant que vous utilisez git qui est en grande partie une norme de facto à ce stade, fin 2018).
Notez que require_relative
utilise le répertoire actuel du fichier avec l' instruction require_relative (donc pas nécessairement votre répertoire actuel à partir duquel vous utilisez la commande). Cela maintient le require_relative
chemin "stable" car il est toujours relatif au fichier le nécessitant de la même manière.
Les meilleures réponses sont correctes, mais profondément techniques. Pour les nouveaux venus chez Ruby:
require_relative
sera très probablement utilisé pour introduire du code à partir d'un autre fichier que vous avez écrit. par exemple, que faire si vous avez des données ~/my-project/data.rb
et que vous souhaitez les inclure ~/my-project/solution.rb
? en 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 du code à partir d'une bibliothèque écrite par quelqu'un d'autre.par exemple, que faire si vous souhaitez utiliser l'une des fonctions d'assistance fournies dans la active_support
bibliothèque? vous devrez 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 pointé par rapport au fichier qui l'appelle.
require
nécessite un fichier inclus dans le $LOAD_PATH
.
Je viens de voir que le code de RSpec a un commentaire sur la require_relative
constante O (1) et la require
linéarité O (N). Donc, la différence est probablement celle qui require_relative
est préférée require
.
require_relative
c'était plus rapide car le chargeur n'a pas à parcourir le chemin de chargement à la recherche du fichier. Essentiellement, require_relative
fournit un lien direct.
Je veux ajouter que lorsque vous utilisez Windows, vous pouvez utiliser require './1.rb'
si le script est exécuté localement ou à partir d'un lecteur réseau mappé mais lorsqu'il est exécuté à partir d'un \\servername\sharename\folder
chemin UNC que vous devez utiliser require_relative './1.rb'
.
Je ne me mêle pas dans la discussion à utiliser pour d'autres raisons.
require_relative
fichier Pourriez-vous s'il vous plaît jeter une idée sur ce stackoverflow.com/questions/43487784/…
$:
. Voir stackoverflow.com/questions/2900370