2009-06-10 14 views
11

Estoy mirando un módulo X que contiene dos módulos llamados "InstanceMethods" y "ClassMethods"."base.send: include, InstanceMethods" ---> ¿Qué hace esto?

La última definición en el módulo X es la siguiente:

def self.included(base) 
    base.send :include, InstanceMethods 
    base.send :extend, ClassMethods 
    end 

¿Qué hace esto?

+1

Yo sé que no es su código, pero tenga en cuenta que no hay necesidad de tener un módulo InstanceMethod: ya se está incluyendo el módulo de matriz, por lo que debería poner los métodos de instancia ahí. – tokland

Respuesta

8

included se vuelve a llamar cada vez que se incluye un módulo a otro módulo o clase. En este caso se tratará de invocar base 'include método s para obtener el módulo de métodos, variables y constantes de InstanceMethods añadido en base y luego intentará invocar base' s extend método para obtener los métodos de instancia de ClassMethods añadió a base.

También podría haber sido

def self.included(base) 
    base.include(InstanceMethods) 
    base.extend(ClassMethods) 
end 
+1

Ok, eso tiene sentido. Hay una clase W que incluye el módulo X, por lo que la idea es que W obtenga todos los métodos de instancia y métodos de clase contenidos en X a través de estos módulos. La pieza que faltaba era cómo se llamaba 'incluido', pero estás diciendo que tan pronto como diga "W include X", se llamará al método incluido(). - franz 0 segundos atrás – franz

+2

Eso es correcto. Hay más información y un ejemplo amigable en http://ruby-doc.org/core/classes/Module.html#M001683 – toholio

+9

include es un método privado de la clase Method. por lo tanto, base.include no funcionará. –

0

Está definiendo un método de clase que toma el parámetro "base". Luego llama a los métodos include y extend en base, pasando el módulo InstanceMethods y ClassMethods como argumentos, respectivamente. La llamada al include agregará los métodos de instancia definidos en InstanceMethods al base. No estoy familiarizado con el método extend, pero supongo que también hará algo así, pero para los métodos de clase.

1

'send' invoca su primer argumento como un método en el objeto invocado, y el resto de los argumentos se envían como argumentos al método. Así pues, en este caso,

base.send :include, InstanceMethods 

es equivalente a

base.include(InstanceMethods) 

que añade los métodos en el módulo InstanceMethods a la 'base' objeto

+2

No es completamente equivalente, ya que 'base.send: include' seguirá llamando inclusive incluso si el método se ha hecho privado. 'base.include' generará un error. –