ruby - 如何将便捷类方法添加到 ruby​​ 中的 Singleton 类

标签 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

这行得通,但是为每个实例方法手动编写一个类方法会相当乏味。这就是 ruby​​,必须有一种巧妙的动态方式来做到这一点。

最佳答案

一种方法是这样的:

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

如果你想更细粒度地控制委托(delegate)哪些方法,那么你可以使用委托(delegate)技术:

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

关于ruby - 如何将便捷类方法添加到 ruby​​ 中的 Singleton 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1480355/

相关文章:

ruby - 在现有 Sinatra 应用程序上使用 Zurb Foundation 的最简单方法?

ruby-on-rails - 如何更新整个表列

docker - 动态发现 Docker Compose

ios - 单例重叠?

java - 任何单例模式早期实例化的问题

c# - WCF 服务方法中单例模式的问题

ruby - 您在 Linux 上为 Ruby 使用什么 IDE/编辑器?

c# - 如何在 C# 中在运行时动态创建和命名对象?

variables - Dart 中的动态类型是否较慢?

ruby - 如何在 Shoes 应用程序中启用文本选择、复制和粘贴?