¿Cuál es la diferencia entre "módulo de inclusión" y "módulo de extensión" en Ruby?
module include (2)
Posible duplicado:
¿Cuál es la diferencia entre incluir y extender 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
¿Se considerará foo
un método de instancia o un método de clase? En otras palabras, es esto equivalente a:
class A
def foo
...
end
end
o para:
class A
def self.foo
...
end
end
?
1) include
métodos de adición, constantes y variables en instancias de clase A
; extend
agrega esas cosas a la instancia de la instancia de Class
A
(que define 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
solo tiene sentido en una Class
o Module
, mientras que la extend
se puede usar para agregar métodos a cualquier Object
.
2) En efecto: cuando se usa include
, foo
es un método de instancia de A
... cuando se usa extend
, foo
es un método de clase.
Escribí un blog publicando sobre esto hace mucho tiempo here .
Cuando está "incluyendo" un módulo, el módulo se incluye como si los métodos se hubieran definido en la clase que los incluye, podría decir que está copiando los métodos a la clase que lo incluye.
Cuando está "extendiendo" un módulo, está diciendo "agregue los métodos de este módulo a esta instancia específica ". Cuando estás dentro de una definición de clase y dices "extender", la "instancia" es el objeto de clase en sí, pero también puedes hacer algo como esto (como en la publicación de 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"
Entonces, no es exactamente un método de clase, sino un método para la "instancia" que llamaste "extender". Mientras lo hace dentro de una definición de clase y la instancia en la que está la clase en sí misma, "parece" un método de clase.