2009-09-26 50 views
5

比方說,我有一個單例類是這樣的:如何方便類方法添加到一個Singleton類紅寶石

class Settings 
    include Singleton 

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

現在,如果我想知道是幹什麼用的超時我需要寫類似:

Settings.instance.timeout 

但我寧願縮短,要

Settings.timeout 

一個明顯的方法,使這項工作將修改imple設置到:

class Settings 
    include Singleton 

    def self.timeout 
    instance.timeout 
    end 

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

這樣的工作,但手動寫出每個實例方法的類方法將是相當繁瑣的。這是紅寶石,必須有一個聰明聰明的動態方式來做到這一點。

回答

10

一種方式來做到這一點是這樣的:

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 

如果你想要更多的細粒度控制上的方法來委派,那麼你可以使用委派技術:

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 

另我推薦使用模塊,如果預期的功能限於行爲,這樣的解決方案將是:

module Settings 
    extend self 

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

end 

Settings.timeout 
+1

真棒回答。在我的特殊情況下,SingleForwardable正是我所期待的。謝謝! – 2009-09-26 16:22:52