¿Cuál es la diferencia entre require relative y require en Ruby?
¿Cuál es la diferencia entre require_relative
y require
en Ruby?
7 answers
Basta con mirar los documentos :
require_relative
complementa el método builtinrequire
al permitirle cargar un archivo que es relativo al archivo que contiene la instrucciónrequire_relative
.Por ejemplo, si tiene clases de prueba unitaria en el directorio "test", y datos para ellas en el directorio "test/data", entonces puede usar una línea como esta en un caso de prueba:
require_relative "data/customer_data_1"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-25 06:41:20
require_relative
es un subconjunto conveniente de require
require_relative('path')
Es igual a:
require(File.expand_path('path', File.dirname(__FILE__)))
Si se define __FILE__
, o se plantea LoadError
de lo contrario.
Esto implica que:
-
require_relative 'a'
andrequire_relative './a'
require relative to the current file (__FILE__
).Esto es lo que desea usar cuando requiera dentro de su biblioteca, ya que no desea que el resultado dependa del directorio actual del llamante.
-
eval('require_relative("a.rb")')
subidasLoadError
porque__FILE__
no está definido dentro deeval
.Esta es la razón por la que no se puede utilizar
require_relative
en las pruebas RSpec, que recibeneval
ed.
Las siguientes operaciones solo son posibles con require
:
require './a.rb'
requiere relativo al directorio actual-
require 'a.rb'
usa la ruta de búsqueda ($LOAD_PATH
) para requerir. No encuentra archivos relativos al directorio o ruta actual.Esto no es posible con
require_relative
porque el los documentos dicen que la búsqueda de rutas solo ocurre cuando "el nombre del archivo no se resuelve en una ruta absoluta" (es decir, comienza con/
o./
o../
), lo que siempre es el caso deFile.expand_path
.
La siguiente operación es posible con ambos, pero querrá usar require
ya que es más corto y más eficiente:
-
require '/a.rb'
yrequire_relative '/a.rb'
ambos requieren la ruta absoluta.
Leyendo la fuente
Cuando los documentos no son claros, recomiendo que eche un vistazo a las fuentes (alternar fuente en los documentos). En algunos casos, ayuda a entender lo que está pasando.
Requiere:
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__
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-27 15:01:33
Desde Ruby API :
Require_relative complementa la builtin método requieren al permitirle para cargar un archivo que es relativo a la archivo que contiene el require_relative instrucción.
Cuando se utiliza require para cargar un archivo, por lo general, está accediendo funcionalidad que ha sido correctamente instalado y accesible, en tu sistema. require no ofrece un buena solución para cargar archivos dentro el código del proyecto. Esto puede ser útil durante una fase de desarrollo, para acceso a los datos de prueba, o incluso para acceder a archivos que están "bloqueados" dentro de un proyecto, no destinado a uso exterior.
Por ejemplo, si tiene prueba unitaria clases en el directorio "test", y datos para ellos bajo la prueba "test/data" directorio, entonces usted podría utilice una línea como esta en un caso de prueba:
require_relative "data/customer_data_1"
Puesto que ni "prueba" ni "prueba / datos" es probable que estar en la ruta de la biblioteca de Ruby (y para una buena razón), un requerir no encuéntralos. require_relative es un buen solución para este problema en particular.
Puede incluir u omitir la extensión (.rb o. so) del archivo que se encuentra carga.
La ruta debe responder a to_str.
Usted puede encontrar la documentación en http://extensions.rubyforge.org/rdoc/classes/Kernel.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-25 10:58:29
Resumen
Use require
para las gemas instaladas
Use require_relative
para archivos locales
require
usa $LOAD_PATH
para encontrar los archivos.
Así es como requiere tales como
require 'date'
Funciona - dependen de que haya instalado (por ejemplo, gem install [package]
) un paquete en algún lugar de su sistema para esa funcionalidad.
Cuando se utiliza require
puede utilizar el formato "./
" para un archivo en el directorio actual, por ejemplo, require "./my_file"
pero eso no es un común o recomendado practica y deberías usar require_relative
en su lugar.
Al usar require_relative
, 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.
Tenga en cuenta que require_relative
utiliza el directorio actual del archivo con la instrucción require_relative (así que no necesariamente su directorio actual).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-16 20:55:55
Las respuestas principales son correctas, pero profundamente técnicas. Para los más nuevos al Rubí {
-
require_relative
probablemente se usará para traer código de otro archivo que escribiste.
Por ejemplo, ¿qué pasa si tienes datos en ~/my-project/data.rb
y quieres incluirlos en ~/my-project/solution.rb
? en solution.rb
añadirías 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 utilice para trae código de una biblioteca que otra persona escribió.
Por ejemplo, ¿qué pasa si desea utilizar una de las funciones auxiliares proporcionadas en la biblioteca active_support
? 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 específicamente apuntado en relación con el archivo que lo llama.require
requiere un archivo incluido en $LOAD_PATH.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-06 17:02:30
Acabo de ver que el código de RSpec tiene algún comentario sobre require_relative
siendo O(1) constante y require
siendo O(N) lineal. Así que probablemente la diferencia es que require_relative
es el preferido que require
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-04 01:32:55
Quiero agregar que al usar Windows puede usar require './1.rb'
si el script se ejecuta local o desde una unidad de red asignada, pero cuando se ejecuta desde una ruta de carpeta UNC \servername\sharename\necesita usar require_relative './1.rb'
No me mezclo en la discusión que utilizar por otras razones.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-03 16:41:18