2010-11-18 8 views

Respuesta

10

Object#extendtiene para ser público, de lo contrario no podrá usarlo. Después de todo, su propósito es mezclar un módulo en un objeto, por lo que generalmente lo llamarías como obj.extend(Foo), que no es posible con métodos privados.

Module#include generalmente se utiliza solamente dentro de un cuerpo del módulo, así:

class Bar 
    include Foo 
end 

es decir, por lo general se llama sin un receptor, por lo que no tiene que ser público. Por supuesto, no es tener para ser privado tampoco.

Mi conjetura es la razón por la que es privado es que es más invasiva, ya que cambia el comportamiento de cada instancia de Bar, mientras que Object#extend sólo se cambia un solo objeto. Por lo tanto, Module#include es en cierto sentido "más peligroso" y por lo tanto se hace privado.

No sé si esa es la verdadera razón, pero es consistente con otros métodos similares como Module#define_method.

+0

No * tiene * que ser. Podrías usarlo si fuera privado: 'obj.send (: extender, Foo)', 'obj.instance_eval {extender Foo}', sin incluir el caso de los módulos 'clase Bar; extender Foo; end' –

+0

@ Marc-AndréLafortune: O clase '<< obj; extender Foo; fin', por supuesto. Como dije, es solo una suposición. –

+0

que estaba respondiendo a su primera frase "objeto' # extend' tiene que ser público, de lo contrario no sería capaz de usarlo." –

1

Para poder ejecutar Foo.include(Bar) en cualquier punto, lo más probable es que sea una fuente de errores muy desagradables.

1

Como complemento a la respuesta de Jörg W Mittag, objeto # extienden también se puede utilizar para incluir métodos de instancia del módulo que se utilizará en el nivel de clase (que también estará disponible para todas las instancias de esa clase):

module Foo 
    def bar (baz) 
    end 
end 

class Qux 
    extend Foo 

    bar 'asdf' 
end 
Cuestiones relacionadas