¿Cuál es la diferencia entre require relative y require en Ruby?


¿Cuál es la diferencia entre require_relative y require en Ruby?

 262
Author: Arup Rakshit, 2010-09-09

7 answers

Basta con mirar los documentos :

require_relative complementa el método builtin require al permitirle cargar un archivo que es relativo al archivo que contiene la instrucción require_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"
 275
Author: miku,
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' and require_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")') subidas LoadError porque __FILE__ no está definido dentro de eval.

    Esta es la razón por la que no se puede utilizar require_relative en las pruebas RSpec, que reciben eval 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 de File.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' y require_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__
 74
Author: Ciro Santilli 新疆改造中心 六四事件 法轮功,
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

 71
Author: svilenv,
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_relativeutiliza el directorio actual del archivo con la instrucción require_relative (así que no necesariamente su directorio actual).

 30
Author: Michael Durrant,
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.

 19
Author: common-nighthawk,
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.

 11
Author: mech,
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.

 0
Author: peter,
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