如何在ruby中将便捷类方法添加到Singleton类中

时间:2009-09-26 03:27:13

标签: ruby dynamic singleton

假设我有一个像这样的单身人士课程:

class Settings
  include Singleton

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

现在,如果我想知道使用什么超时,我需要编写类似的内容:

Settings.instance.timeout

但我宁愿将其缩短为

Settings.timeout

实现这项工作的一个显而易见的方法是将“设置”的实现修改为:

class Settings
  include Singleton

  def self.timeout
    instance.timeout
  end

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

这样可行,但为每个实例方法手动编写一个类方法会相当繁琐。这是红宝石,必须有一种聪明聪明的动态方法来做到这一点。

1 个答案:

答案 0 :(得分: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