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

Respuestas:

543

¿Cuál es la diferencia entre "incluir" y "requerir" en Ruby?

Responder:

Los métodos de incluir y requerir hacen cosas muy diferentes.

El método require hace lo que incluye does en la mayoría de los otros lenguajes de programación: ejecutar otro archivo. También rastrea lo que ha requerido en el pasado y no requerirá el mismo archivo dos veces. Para ejecutar otro archivo sin esta funcionalidad adicional, puede usar el método de carga.

El método include toma todos los métodos de otro módulo y los incluye en el módulo actual. Esta es una cosa de nivel de lenguaje en lugar de una cosa de nivel de archivo como requiere. El método de inclusión es la forma principal de "extender" las clases con otros módulos (generalmente conocidos como mix-ins). Por ejemplo, si su clase define el método "cada uno", puede incluir el módulo mixin Enumerable y puede actuar como una colección. Esto puede ser confuso ya que el verbo include se usa de manera muy diferente en otros idiomas.

Fuente

Entonces, si solo desea usar un módulo, en lugar de extenderlo o hacer una mezcla, entonces querrá usarlo require.

Por extraño que parezca, Ruby's requirees análogo a C's include, mientras que Ruby's includeno se parece en nada a C's include.

HanClinto
fuente
45
De hecho, la inclusión de C no carga un archivo como se requiere, sino que reemplaza la línea #include por el contenido del archivo. Los archivos incluidos no tienen que ser 'encabezado' y #include no tiene que estar al principio del archivo, pero puede estar en cualquier lugar, como en la clase o incluso una definición de método. Esto significa que puede mezclar en C ++ escribiendo algunos métodos en un archivo e incluirlo en el código de una clase, exactamente como lo haría en ruby. Por lo tanto, no están tan lejos, a pesar de que en realidad no es una práctica común en las C.
mb14
13
Esta respuesta podría beneficiarse al incluir ejemplos.
Travis Bear
12
El comentario de mb14 implica esto, pero vale la pena decirlo explícitamente: al contrario de lo que dice la respuesta, require no "ejecuta" un archivo, sino que lo carga como si fuera parte del archivo contenedor. Esto puede parecer una trampa semántica, pero en realidad es una diferencia bastante importante.
Lonny Eachus
Gran explicación Gracias por llevar el punto a casa con la última declaración: "Curiosamente, el requerimiento de Ruby es análogo a la inclusión de C, mientras que la inclusión de Ruby no se parece en nada a la inclusión de C".
ArtSabintsev
1
@GregSchmit: includeen Ruby es simplemente herencia. class C; include M endhace Mla superclase de Cy la (antigua) superclase de Cla superclase de M. No creo que C includefuncione a través de la herencia, creo que es una simple sustitución textual / léxica.
Jörg W Mittag
100

Si está utilizando un módulo, eso significa que está incorporando todos los métodos a su clase. Si tiene extenduna clase con un módulo, eso significa que está "incorporando" los métodos del módulo como métodos de clase . Si tiene includeuna clase con un módulo, eso significa que está "incorporando" los métodos del módulo como métodos de instancia .

EX:

 module A
   def say
     puts "this is module A"
   end
 end

 class B
   include A
 end

 class C
   extend A
 end

B.say => método indefinido 'decir' para B: Clase

B.new.say => este es el módulo A

C.say => este es el módulo A

C.new.say => método indefinido 'decir' para C: Clase

Peter Dang
fuente
23
Creo que esto no responde la pregunta, pero es lo que estaba buscando =)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
2
En realidad, esto no responde a la pregunta de cuáles son las diferencias entre requirey include.
94

Del libro Metaprogramming Ruby,

El require()método es bastante similar load(), pero está destinado a un propósito diferente. Usas load()para ejecutar código y require()para importar bibliotecas.

Pratik Khadloya
fuente
73
Voto a favor por no comparar con otro idioma en tu respuesta :)
Stevo
Voto negativo para no proporcionar una respuesta en el contexto de la pregunta: "¿Si solo quiero usar los métodos de un módulo en mi clase?"
benc
57
  • Ruby requirees más como "incluir" en otros lenguajes (como C). Le dice a Ruby que desea traer el contenido de otro archivo . Mecanismos similares en otros idiomas son:

  • Ruby includees un mecanismo de herencia orientado a objetos utilizado para mixins .

Hay una buena explicación aquí :

[La] respuesta simple es que require e include son esencialmente no relacionadas.

"require" es similar al C include, lo que puede causar confusión para los novatos. (Una diferencia notable es que los locales dentro del archivo requerido "se evaporan" cuando se hace el requerimiento).

La inclusión de Ruby no es nada como la inclusión de C. La instrucción include "mezcla" un módulo en una clase. Es una forma limitada de herencia múltiple . Un módulo incluido literalmente otorga una relación "es-a" en la cosa que lo incluye.

Énfasis añadido.

bradheintz
fuente
7

¿Alguna vez has intentado con requireun módulo? ¿Cuáles fueron los resultados? Sólo inténtalo:

MyModule = Module.new
require MyModule # see what happens

No se pueden requerir módulos, ¡solo se incluyen!

Boris Stitnicky
fuente
La afirmación aquí no es correcta. Se pueden requerir módulos. Y cualquiera que ejecute el código anterior encontrará que recibe el mismo resultado ( TypeError) si la palabra Modulese cambia a Class.
pjd
7

Desde la programación de Ruby 1.9

Haremos un par de puntos sobre la declaración de inclusión antes de continuar. Primero, no tiene nada que ver con los archivos. Los programadores de C usan una directiva de preprocesador llamada #include para insertar el contenido de un archivo en otro durante la compilación. La declaración de inclusión de Ruby simplemente hace referencia a un módulo. Si ese módulo está en un archivo separado, debe usar require (o su primo menos usado, cargar) para arrastrar ese archivo antes de usar include. En segundo lugar, una inclusión de Ruby no simplemente copia los métodos de instancia del módulo en la clase. En cambio, hace una referencia de la clase al módulo incluido. Si varias clases incluyen ese módulo, todas apuntarán a lo mismo. Si cambia la definición de un método dentro de un módulo, incluso mientras su programa se está ejecutando,

cizixs
fuente
3

Incluir Cuando incluye un módulo en su clase como se muestra a continuación, es como si tomara el código definido dentro del módulo y lo insertara dentro de la clase, donde lo 'incluye'. Permite el comportamiento 'mixin'. Se utiliza para SECAR su código para evitar la duplicación, por ejemplo, si hubiera varias clases que necesitarían el mismo código dentro del módulo.

Carga El método de carga es casi como el método requerido, excepto que no realiza un seguimiento de si esa biblioteca se ha cargado o no. Por lo tanto, es posible cargar una biblioteca varias veces y también cuando se utiliza el método de carga debe especificar la extensión ".rb" del nombre del archivo de la biblioteca.

Requerir El método require le permite cargar una biblioteca y evita que se cargue más de una vez. El método require devolverá 'false' si intenta cargar la misma biblioteca después de la primera vez. El método require solo debe usarse si la biblioteca que está cargando se define en un archivo separado, que suele ser el caso.

Puede preferir esto http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/

Sanket
fuente
3

A continuación se presentan algunas diferencias básicas entre requerir e incluir:

Exigir:

  1. Requerir lee el archivo del sistema de archivos, lo analiza, lo guarda en la memoria y lo ejecuta en un lugar determinado, lo que significa que si incluso cambia algo mientras se ejecuta el script, ese cambio no se reflejará.
  2. Requerimos el archivo por nombre, no por el nombre del módulo.
  3. Normalmente se usa para bibliotecas y extensiones.

Incluir:

  1. Cuando incluye un módulo en su clase, se comporta como si tomara el código definido en su módulo y lo insertara en su clase.
  2. Incluimos el nombre del módulo, no el nombre del archivo.
  3. Por lo general, se usa para secar el código y eliminar la duplicación en el código.
Awais Shafqat
fuente
2
require(name)

Volverá bolean verdadero / falso

El nombre que se pasa como parámetro al requisito, ruby ​​intentará encontrar el archivo fuente con ese nombre en su ruta de carga. El método require devolverá 'false' si intenta cargar la misma biblioteca después de la primera vez. El método require solo debe usarse si la biblioteca que está cargando está definida en un archivo separado. Por lo tanto, realiza un seguimiento de si esa biblioteca ya estaba cargada o no.

include module_name

Supongamos que tiene algunos métodos que necesita tener en dos clases diferentes. Entonces no tienes que escribirlos en ambas clases. En cambio, lo que puede hacer es definirlo en el módulo. Y luego incluya este módulo en otras clases. Ruby lo proporciona solo para garantizar el principio DRY. Se utiliza para SECAR su código para evitar duplicaciones

Shrinivas
fuente
2

Incluir

Cuando ingresa includeun módulo en su clase, es como si tomara el código definido dentro del módulo y lo insertara dentro de la clase, donde lo 'incluye'. Permite el comportamiento 'mixin'. Se utiliza para SECAR su código para evitar la duplicación, por ejemplo, si hubiera varias clases que necesitarían el mismo código dentro del módulo.

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  include Log 
  # ... 
end

tc = TestClass.new.class_type # -> success
tc = TestClass.class_type # -> error

Exigir

El método require le permite cargar una biblioteca y evita que se cargue más de una vez. El método require devolverá 'false' si intenta cargar la misma biblioteca después de la primera vez. El método require solo debe usarse si la biblioteca que está cargando se define en un archivo separado, que suele ser el caso.

Por lo tanto, realiza un seguimiento de si esa biblioteca ya estaba cargada o no. Tampoco necesita especificar la extensión ".rb" del nombre del archivo de la biblioteca. Aquí hay un ejemplo de cómo usar require. Coloque el método require en la parte superior de su archivo ".rb":

Carga

El método de carga es casi como el método requerido, excepto que no realiza un seguimiento de si esa biblioteca se ha cargado o no. Por lo tanto, es posible cargar una biblioteca varias veces y también cuando se utiliza el método de carga debe especificar la extensión ".rb" del nombre del archivo de la biblioteca.

Ampliar

Al usar el método extendido en lugar de incluir, está agregando los métodos del módulo como métodos de clase en lugar de como métodos de instancia.

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  extend Log 
  # ... 
end

tc = TestClass.class_type
Imran Ahmad
fuente
2

'Cargar': inserta el contenido de un archivo. (Analiza el archivo cada vez que se llama al archivo)

'Requerir': inserta un contenido analizado del archivo (archivo analizado una vez y almacenado en la memoria)

'Incluir': incluye el módulo en la clase y puede usar métodos dentro del módulo como método de instancia de la clase

'Extender': incluye el módulo en la clase y puede usar métodos dentro del módulo como método de clase

Vaishali Venkatesan
fuente