2009-09-26 10 views
5

Digamos que tengo una clase Singleton así:Cómo agregar métodos de la clase de conveniencia a una clase Singleton en rubí

class Settings 
    include Singleton 

    def timeout 
    # lazy-load timeout from config file, or whatever 
    end 
end 

Ahora, si yo quiero saber qué tiempo de espera para utilizar tengo que escribir algo como:

Settings.instance.timeout 

pero prefiero que acortar a

Settings.timeout 

Una manera obvia de hacer este trabajo sería modificar la imple mentación de los ajustes a:

class Settings 
    include Singleton 

    def self.timeout 
    instance.timeout 
    end 

    def timeout 
    # lazy-load timeout from config file, or whatever 
    end 
end 

que funciona, pero sería bastante tedioso para escribir manualmente a cabo un método de clase para cada método de instancia. Esto es Ruby, debe haber una forma inteligente inteligente de hacer esto.

Respuesta

10

Una forma de hacerlo es la siguiente:

require 'singleton' 
class Settings 
    include Singleton 

    # All instance methods will be added as class methods 
    def self.method_added(name) 
    instance_eval %Q{ 
     def #{name} 
     instance.send '#{name}' 
     end 
    } 
    end 


    def timeout 
    # lazy-load timeout from config file, or whatever 
    end 
end 

Settings.instance.timeout 
Settings.timeout 

Si desea un control de grano más fino sobre los métodos para delegar, a continuación, puede utilizar técnicas de delegación:

require 'singleton' 
require 'forwardable' 
class Settings 
    include Singleton 
    extend SingleForwardable 

    # More fine grained control on specifying what methods exactly 
    # to be class methods 
    def_delegators :instance,:timeout,:foo#, other methods 

    def timeout 
    # lazy-load timeout from config file, or whatever 
    end 

    def foo 
    # some other stuff 
    end 

end 

Settings.timeout 

Settings.foo 

Por otro lado, recomiendo usar módulos si la funcionalidad prevista se limita al comportamiento, tal solución sería:

module Settings 
    extend self 

    def timeout 
    # lazy-load timeout from config file, or whatever 
    end 

end 

Settings.timeout 
+1

Awesome responder. En mi caso particular, SingleForwardable es exactamente lo que estaba buscando. ¡Gracias! –

Cuestiones relacionadas