2009-09-26 43 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