¿Cuál es la diferencia entre require_relativey requireen Ruby?
¿Cuál es la diferencia entre require_relativey requireen Ruby?
Respuestas:
Solo mira los documentos :
require_relativecomplementa el método incorporadorequirepermitiéndole cargar un archivo que es relativo al archivo que contiene larequire_relativedeclaració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_relativele permite "cargar un archivo que es relativo al archivo que contiene la require_relativedeclaración ". Con require, ./indica una ruta que es relativa a su directorio de trabajo actual.
require strsiempre buscará en los directorios en $ LOAD_PATH. Debe usarlo require_relativecuando el archivo que necesita cargar existe en algún lugar relativo al archivo que requiere la carga. Reserva requirepara 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 LoadErrorcontrario.
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 LoadErrorporque __FILE__no está definido por dentro eval.
Es por eso que no se puede usar require_relativeen 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_relativeporque 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 requireya 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
requirepara gemas instaladasrequire_relativepara archivos localesrequireusa tu $LOAD_PATHpara encontrar los archivos.
require_relativeusa 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_relativeen 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_relativeutiliza 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_relativeruta "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.rby desea incluirlos ~/my-project/solution.rb? en la solution.rbque 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_supportbiblioteca? necesitará instalar la gema con gem install activesupporty 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.
requirerequiere un archivo incluido en el $LOAD_PATH.
Acabo de ver que el código de RSpec tiene algún comentario sobre require_relativeser O (1) constante y requireser O (N) lineal. Entonces, probablemente la diferencia es que require_relativees la preferida require.
require_relativeera más rápido porque el cargador no tiene que atravesar la ruta de carga en busca del archivo. Básicamente, require_relativeproporciona 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\folderruta 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