2011-03-30 9 views
19

Estoy tratando de definir un par de módulos de agregar fácilmente en algunos métodos de instancia y de clase a otras clases, esto es lo que estoy haciendo:rubí - Módulo extienden dentro de otro módulo de

module Foo 
    module Bar 
    def speak 
     puts "hey there" 
    end 
    end 
    module Baz 
    extend Foo::Bar 

    def welcome 
     puts "welcome, this is an instance method" 
    end 
    end 
end 

class Talker 
    include Foo::Baz 
end 

Talker.new.welcome 
Talker.speak 

La salida de esto es:

welcome, this is an instance method 
undefined method 'speak' for Talker.class (NoMethodError) 

que estaba esperando a transmisor tiene el método del 'hablar' ya que incluye Foo :: Baz que a su vez se extiende Foo :: Bar.

¿Qué me estoy perdiendo?

+0

así que si hago de Baz una clase en lugar de un módulo y cambio Talker para que subclasifique Baz, mi ejemplo funciona. Pero, ¿es posible hacer lo que estaba tratando de hacer sin convertir a Baz en una clase? (y sin tener que hacer algo como Talker :: Foo :: Bar.speak?) – codecraig

Respuesta

20

Puede probar esto:

module Baz 
    extend Foo::Bar 

    def self.included(base) 
    base.send :extend, Foo::Bar 
    end 

    def welcome 
    puts "welcome, this is an instance method" 
    end 
end 

Esta voluntad de auto-se extienden a todas las clases de que Baz está incluido

+0

¡agradable, gracias! eso me da lo que quería. – codecraig

+1

¿Por qué 2 extender Foo :: Bar? uno está dentro incluido y uno está afuera. – shajin

+1

La primera extensión agrega métodos de nivel de clase de Foo :: Bar a Baz. El segundo agrega métodos de Foo :: Bar a todas las clases y módulos que incluyen Baz. –

4

probar esto:

class Talker 
    extend Foo::Baz 
end 

ya que desea llamar Talker.speak como un método de la clase y no como un método de instancia (como Talker.new.speak) tiene que incluir la Foo: Baz en una forma en que la clase tomará los métodos en sí.

Una posibilidad es el uso de 'extender' (como el anterior) y el otro es la modificación es eigenclass:

class Talker 
    class << self 
    include Foo::Baz 
    end 
end 
Cuestiones relacionadas