2010-09-08 16 views

Respuesta

255

basta con ver el docs:

require_relative complementa el método incorporado require por lo que le permite cargar un archivo que es relativa al archivo que contiene la declaración require_relative.

Por ejemplo, si usted tiene clases de prueba en el directorio "test", y los datos para ellos bajo el directorio test "prueba/datos", entonces usted podría usar una línea como esta en un caso de prueba:

require_relative "data/customer_data_1" 
+20

¿Hay alguna diferencia entre 'require './File.rb'' y' require_relative' file.rb''? –

+49

@CiroSantilli Sí. 'require_relative' le permite" cargar un archivo que es ** relativo al archivo que contiene la declaración 'require_relative' **". Con 'require','./'Indica una ruta relativa a su directorio de trabajo actual. – Ajedi32

+8

Creo que es más importante tener en cuenta que 'require str' siempre buscará a través de directorios en $ LOAD_PATH. Debe usar 'require_relative' cuando el archivo que necesita cargar existe en algún lugar en relación con el archivo que solicita la carga. Reserva 'require' para dependencias" externas ". – rthbound

69

de Rubí API:

require_relative complementa el método incorporado requerir por lo que le para cargar un archivo que es relativo a t El archivo contiene la declaración require_relative .

Cuando se utiliza requieren para cargar un archivo, que está accediendo normalmente funcionalidad que ha sido correctamente instalado y accesibles, 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 los datos de prueba, o incluso para acceder a los archivos que están "bloqueados" dentro de un proyecto, no destinado a fuera de uso.

Por ejemplo, si usted tiene prueba de la unidad clases en el directorio "test", datos para ellos bajo el directorio de prueba "prueba/datos", entonces es posible que usar una línea como esta en un caso de prueba :

require_relative "data/customer_data_1" 

Dado que ni "prueba" ni "pruebas/datos" es probable que estar en ruta de la biblioteca de Ruby (y para buena razón), uno normal no requieren las encontrarán. 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 .

ruta debe responder a to_str.

Puede encontrar la documentación en http://extensions.rubyforge.org/rdoc/classes/Kernel.html

11

acabo de ver el código de la RSpec tiene algún comentario sobre require_relative siendo O (1) constante y lineal require O (N) siendo. Entonces, probablemente la diferencia es que require_relative es el preferido que require.

+0

Interesante. Aterricé aquí buscando información sobre una comparación de velocidad. Mi idea era que 'require_relative' era más rápido porque el cargador no tenía que atravesar la ruta de carga en busca del archivo. Esencialmente, 'require_relative' proporciona un enlace directo. –

+0

Discusión anticipada sobre [velocidad relativa obligatoria] (https://www.ruby-forum.com/topic/2990962) y el RSpec [changelog] (https://github.com/rspec/rspec-core/blob/master/ Changelog.md # 280rc2--2011-12-19). –

64

require_relative es un subconjunto conveniente de require

require_relative('path') 

es igual a:

require(File.expand_path('path', File.dirname(__FILE__))) 

si se ha definido __FILE__, o se plantea LoadError lo contrario.

Esto implica que:

  • require_relative 'a' y require_relative './a' requieren en relación con el archivo actual (__FILE__).

    Esto es lo que desea usar cuando lo necesite 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")') plantea LoadError porque __FILE__ no está definido dentro de eval.

    Es por eso que no puede usar require_relative en las pruebas RSpec, que obtienen eval ed.

Las siguientes operaciones sólo son posibles con require:

  • require './a.rb' requiere relativa al directorio actual

  • require 'a.rb' utiliza la ruta de búsqueda ($LOAD_PATH) exigir. No encuentra archivos relativos al directorio o ruta actual.

    Esto no es posible con require_relative debido a que los documentos dicen que la búsqueda de ruta sólo ocurre cuando "el nombre del archivo no se resuelve en una ruta absoluta" (es decir, comienza con / o ./ o ../), que es siempre el caso para File.expand_path.

La siguiente operación es posible con ambos, pero tendrá que utilizar require ya que es más corto y más eficiente:

  • require '/a.rb' y require_relative '/a.rb' ambos requieren la ruta absoluta.

Lectura de la fuente de

Cuando los documentos no están claras, recomiendo que usted echa un vistazo a las fuentes (alternar la fuente de los documentos). En algunos casos, ayuda a comprender lo que está sucediendo.

requieren:

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__ 
25

require utiliza el directorio actual que está ejecutando el programa desde

require_relative utiliza el directorio de donde ese programa en sí reside

Por ejemplo, si un programa está en ~/code y se llama 1.rby has hecho un cd a ese directorio

cd ~/code 

y tratas de ejecutar el programa de rubí con

ruby 1.rb 

entonces dentro 1.rb

require './2.rb' 
require_relative '3.rb' 

tanto va a funcionar.

Sin embargo si se encuentra en otro directorio, dicen

cd ~/tmp 

y tratas de ejecutar el programa con

ruby ../1.rb 

continuación obtendrá un error como

/home/durrantm/.rvm/rubies/ruby-2.1.2/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- ./2.rb (LoadError) 
    from /home/durrantm/.rvm/rubies/ruby-2.1.2/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require' 
    from ../1.rb:1:in `<main>' 

cuando intente ing utilizar

require './2.rb' 

mientras que el uso de

require_relative '3.rb' 

todavía funciona bien _because la referencia (a 3.rb) es relativa a qué directorio del programa (1.rb) se encuentra en.

0

I desea agregar que al usar Windows puede usar require './1.rb' si el script se ejecuta localmente o desde una unidad de red mapeada, pero cuando se ejecuta desde UNC \ servername \ sharename \ folde r ruta que necesita utilizar require_relative './1.rb' No me mezclo en la discusión que utilizar por otros motivos.

+0

lo que quería saber cómo se carga el archivo 'require_relative' Podría por favor lanzar una idea en este http://stackoverflow.com/questions/43487784/appiumruby-load-error-in-the-gem –

8

Las respuestas principales son correctas, pero muy técnicas. Para los más nuevos en la Ruby--

  • require_relative lo más probable ser utilizado para traer código de otro archivo que grabó.

por ejemplo, ¿qué sucede si tiene datos en ~/my-project/data.rb y desea incluirlos en ~/my-project/solution.rb? en solution.rb agregarí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 el código de una biblioteca que alguien más escribió.

por ejemplo, ¿qué sucede si desea utilizar una de las funciones auxiliares proporcionadas en la biblioteca active_support? necesitarás instalar la gema con gem install activesupport y luego en el archivo require 'active_support'.

require 'active_support/all' 
"FooBar".underscore 

Said differently--

  • require_relative requiere un archivo al que apunta específicamente a la relativa al archivo que lo llama.

  • require requiere un archivo incluido en $ LOAD_PATH.

+0

Solo respuesta que entendí. – CapturedTree

+0

¿Cómo puedo votar esta respuesta y llevarla hasta la cima, para que cada visitante de esta página de preguntas obtenga una respuesta clara y comprensible de inmediato sin romperse el sesgo? – GordonFreaman

Cuestiones relacionadas