Si inicializo un objeto como este:

a = A.new
a.extend(B)

¿Es eso diferente de hacer lo siguiente?

a = A.new.tap do |a|
  include B
end
0
Darth Egregious 25 ene. 2016 a las 22:54

3 respuestas

La mejor respuesta

No, ambas no son equivalentes. No, ambos no son equivalentes.

a.extend(B) agrega los métodos del módulo B solo a la instancia a, mientras que

a = A.new.tap do |a|
  include B
end

Es equivalente a

include B

Dentro del bloque de tap, el self actual es main y siempre que incluyas un módulo en main, los métodos del módulo incluido se convierten en métodos de instancia de Object clase, como se muestra a continuación:

class A
  def class_meth
    "class meth"
  end
end

module B
  def module_meth
    "module meth"
  end
end
p Object.instance_methods
#=> [:nil?, :===, :=~, :!~,...
a = A.new.tap do |a|
  include B
end
p Object.instance_methods
#=> [:module_meth, :nil?, :===, :=~,...

Por tanto, sientes que el efecto es similar a a.extend(B), pero es mucho más. Cualquier objeto nuevo de cualquier clase tendrá métodos de módulo B en ellos a través de la clase Object.

class C
end

p C.instance_methods
#=> [:module_meth, :nil?, :===, :=~, :!~,...

p Hash.instance_methods.grep(/module_meth/)
#=> [:module_meth]

p [].module_meth
#=> "module meth"
2
Wand Maker 25 ene. 2016 a las 20:20

Ellas no son iguales Ellos no son iguales

Extender es método si la clase de objeto incluye es método si clase de módulo

Entonces, si lo haces

object.extend(Module)

Agregará métodos del módulo al objeto, pero

SomeClass.include(Module)

Agregará métodos del módulo a la instancia de SomeClass

-1
edikgat 25 ene. 2016 a las 20:32

include y extend no son lo mismo. include solo puede agregar métodos a nivel de instancia, mientras que las extensiones "incluyen" mucho más:

Pero hay ocasiones en las que desearía incluir algunos métodos de un módulo como métodos de nivel de clase en una clase. Aquí es donde el método extender se vuelve útil.

Esta es solo una diferencia de alto nivel, hay muchas más diferencias, como que include está limitado en los escenarios en los que puede funcionar; puede lea más aquí.

0
Martin Konecny 25 ene. 2016 a las 20:01