2011-01-17 30 views
19

Duplicar posible:
What is the difference between include and extend in Ruby?¿Cuál es la diferencia entre "incluir módulo" y "extender módulo" en Ruby?

Dado:

module my_module 
    def foo 
    ... 
    end 
end 

Pregunta 1

¿Cuál es la diferencia entre:

class A 
    include my_module 
end 

y

class A 
    extend my_module 
end 

Pregunta 2

Will foo ser considerado un método de instancia o un método de clase? En otras palabras, ¿es equivalente a:

class A 
    def foo 
    ... 
    end 
end 

oa:

class A 
    def self.foo 
    ... 
    end 
end 

?

Respuesta

25

Escribí un blog publicando sobre esto hace mucho tiempo here.

Cuando "incluye" un módulo, el módulo se incluye como si los métodos se definieran en la clase que los incluye, puede decir que está copiando los métodos a la clase incluida.

Cuando "extiende" un módulo, está diciendo "agregue los métodos de este módulo al esta instancia específica". Cuando estás dentro de una definición de clase y decir "extender" la "instancia" es el propio objeto de la clase, pero también se podría hacer algo como esto (como en mi blog anterior):

module MyModule 
    def foo 
    puts "foo called" 
    end 
end 

class A 
end 

object = A.new 
object.extend MyModule 

object.foo #prints "foo called"  

lo tanto, es no es exactamente un método de clase, sino un método para la "instancia" que llamaste "extender". Como lo está haciendo dentro de una definición de clase y la instancia en la que está la clase en sí, "parece" un método de clase.

14

1) include agrega métodos, constantes y variables en las instancias de la clase A; extend agrega esas cosas a la instancia de la instancia ClassA (definiendo efectivamente los métodos de clase).

include my_module permitirá esto: A.new.foo

extend my_module permitirá esto: A.foo

De manera más general, include sólo tiene sentido en un Class o Module, mientras extend se puede utilizar para agregar métodos a cualquier Object.

2) En efecto: cuando se utiliza include, foo es un método de instancia de A ... cuando se utiliza extend, foo es un método de clase.

Cuestiones relacionadas