¿Cuál es la diferencia entre require_relative
y require
en Ruby?
¿Cuál es la diferencia entre require_relative
y require
en Ruby?
Respuestas:
Solo mira los documentos :
require_relative
complementa el método incorporadorequire
permitiéndole cargar un archivo que es relativo al archivo que contiene larequire_relative
declaración.Por ejemplo, si tiene clases de prueba unitaria en el directorio "prueba" y datos para ellas en el directorio "prueba / datos" de prueba, entonces puede usar una línea como esta en un caso de prueba:
require_relative "data/customer_data_1"
require './file.rb'
y require_relative 'file.rb'
?
require_relative
le permite "cargar un archivo que es relativo al archivo que contiene la require_relative
declaración ". Con require
, ./
indica una ruta que es relativa a su directorio de trabajo actual.
require str
siempre buscará en los directorios en $ LOAD_PATH. Debe usarlo require_relative
cuando el archivo que necesita cargar existe en algún lugar relativo al archivo que requiere la carga. Reserva require
para dependencias "externas".
require_relative
es un subconjunto conveniente de require
require_relative('path')
es igual a:
require(File.expand_path('path', File.dirname(__FILE__)))
si __FILE__
está definido, o plantea lo LoadError
contrario.
Esto implica que:
require_relative 'a'
y require_relative './a'
requiere relativo al archivo actual ( __FILE__
).
Esto es lo que desea usar cuando lo requiera dentro de su biblioteca, ya que no desea que el resultado dependa del directorio actual de la persona que llama.
eval('require_relative("a.rb")')
aumenta LoadError
porque __FILE__
no está definido por dentro eval
.
Es por eso que no se puede usar require_relative
en las pruebas de RSpec, que se editan eval
.
Las siguientes operaciones solo son posibles con require
:
require './a.rb'
requiere relativo al directorio actual
require 'a.rb'
utiliza la ruta de búsqueda ( $LOAD_PATH
) para requerir. No encuentra archivos relativos al directorio o ruta actual.
Esto no es posible require_relative
porque los documentos dicen que la búsqueda de ruta solo ocurre cuando "el nombre de archivo no se resuelve en una ruta absoluta" (es decir, comienza con /
or ./
o ../
), que es siempre el caso File.expand_path
.
La siguiente operación es posible con ambos, pero querrá usarla require
ya que es más corta y más eficiente:
require '/a.rb'
y require_relative '/a.rb'
ambos requieren el camino absoluto.Leyendo la fuente
Cuando los documentos no están claros, le recomiendo que eche un vistazo a las fuentes (alternar la fuente en los documentos). En algunos casos, ayuda a entender lo que está sucediendo.
exigir:
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());
}
Esto nos permite concluir que
require_relative('path')
es lo mismo que:
require(File.expand_path('path', File.dirname(__FILE__)))
porque:
rb_file_absolute_path =~ File.expand_path
rb_file_dirname1 =~ File.dirname
rb_current_realfilepath =~ __FILE__
De la API de Ruby :
require_relative complementa el método incorporado require al permitirle cargar un archivo que es relativo al archivo que contiene la declaración require_relative.
Cuando utiliza require para cargar un archivo, generalmente está accediendo a la funcionalidad que se instaló correctamente y se hizo accesible en su sistema. require no ofrece una buena solución para cargar archivos dentro del código del proyecto. Esto puede ser útil durante una fase de desarrollo, para acceder a datos de prueba, o incluso para acceder a archivos que están "bloqueados" dentro de un proyecto, no destinados a uso externo.
Por ejemplo, si tiene clases de prueba unitaria en el directorio "prueba" y datos para ellas en el directorio "prueba / datos" de prueba, entonces puede usar una línea como esta en un caso de prueba:
require_relative "data/customer_data_1"
Como es probable que ni "prueba" ni "prueba / datos" estén en la ruta de la biblioteca de Ruby (y por una buena razón), un requerimiento normal no los encontrará. require_relative es una buena solución para este problema en particular.
Puede incluir u omitir la extensión (.rb o .so) del archivo que está cargando.
la ruta debe responder a to_str.
Puede encontrar la documentación en http://extensions.rubyforge.org/rdoc/classes/Kernel.html
require
para gemas instaladasrequire_relative
para archivos localesrequire
usa tu $LOAD_PATH
para encontrar los archivos.
require_relative
usa la ubicación actual del archivo usando la instrucción
Requerir depende de que haya instalado (por ejemplo gem install [package]
) un paquete en algún lugar de su sistema para esa funcionalidad.
Cuando lo use require
, puede usar el ./
formato " " para un archivo en el directorio actual, por ejemplo, require "./my_file"
pero esa no es una práctica común o recomendada y debe usarla require_relative
en su lugar.
Esto simplemente significa incluir el archivo 'relativo a la ubicación del archivo con la declaración require_relative'. En general, recomiendo que los archivos estén "dentro" del árbol de directorios actual en lugar de "arriba", por ejemplo , no use
require_relative '../../../filename'
(hasta 3 niveles de directorio) dentro del sistema de archivos porque eso tiende a crear dependencias innecesarias y frágiles. Sin embargo, en algunos casos, si ya está 'profundo' dentro de un árbol de directorios, puede ser necesario "subir y bajar" otra rama de árbol de directorios. Tal vez de manera más simple, no use require_relative para archivos fuera de este repositorio (suponiendo que esté usando git, que es en gran medida un estándar de facto en este momento, a fines de 2018).
Tenga en cuenta que require_relative
utiliza el directorio actual del archivo con la instrucción require_relative (por lo que no necesariamente es el directorio actual desde el que está utilizando el comando). Esto mantiene la require_relative
ruta "estable", ya que siempre será relativa al archivo que lo requiere de la misma manera.
Las principales respuestas son correctas, pero profundamente técnicas. Para los más nuevos en Ruby:
require_relative
lo más probable es que se use para traer código de otro archivo que usted escribió. por ejemplo, ¿qué pasa si tiene datos ~/my-project/data.rb
y desea incluirlos ~/my-project/solution.rb
? en la solution.rb
que se sumaría require_relative 'data'
.
Es importante tener en cuenta que estos archivos no necesitan estar en el mismo directorio. require_relative '../../folder1/folder2/data'
También es válido.
require
lo más probable es que se use para traer código de una biblioteca que alguien más escribió.por ejemplo, ¿qué sucede si desea usar una de las funciones auxiliares proporcionadas en la active_support
biblioteca? necesitará instalar la gema con gem install activesupport
y luego en el archivo require 'active_support'
.
require 'active_support/all'
"FooBar".underscore
Dicho de otra manera
require_relative
requiere un archivo apuntado específicamente en relación con el archivo que lo llama.
require
requiere un archivo incluido en el $LOAD_PATH
.
Acabo de ver que el código de RSpec tiene algún comentario sobre require_relative
ser O (1) constante y require
ser O (N) lineal. Entonces, probablemente la diferencia es que require_relative
es la preferida require
.
require_relative
era más rápido porque el cargador no tiene que atravesar la ruta de carga en busca del archivo. Básicamente, require_relative
proporciona un enlace directo.
Quiero agregar que cuando use Windows puede usar require './1.rb'
si el script se ejecuta localmente o desde una unidad de red asignada, pero cuando se ejecuta desde una \\servername\sharename\folder
ruta UNC , debe usarlo require_relative './1.rb'
.
No me mezclo en la discusión sobre cuál usar por otras razones.
$:
. Ver stackoverflow.com/questions/2900370