如何像在 Prime 类中一样在 Ruby 中创建默认实例?

Posted

技术标签:

【中文标题】如何像在 Prime 类中一样在 Ruby 中创建默认实例?【英文标题】:How to make a default instance in Ruby as in Prime class? 【发布时间】:2015-05-28 19:21:31 【问题描述】:

我想创建一个可以通过“require”或“require_relative”加载/需要的类或模块。但是,为了简单起见,我不想实例化任何对象,只需开始使用它的方法,类似于 Ruby 的 Prime 类。我怎样才能做到这一点?

require "my_module"
puts My_module.convert("data")

而不是这个:

require "my_module"
an_instance = My_module::My_class.new
puts an_instance.convert("data")

http://ruby-doc.org/stdlib-1.9.3/libdoc/prime/rdoc/Prime.html

【问题讨论】:

"...我不想实例化任何对象,..." 似乎与问题的标题相矛盾。如果convert 是模块方法,require "my_module"; puts My_module.convert("data") 工作正常:module My_module; def self.convert(str)...。这就是你要找的吗? 【参考方案1】:

Prime 类使用singleton pattern 来实现此行为,然后uses a clever trick 使所有实例方法看起来好像它们是类方法。但是,我真的不明白为什么要这样做。如果需要保持一些全局状态,单例模式会很有用,但Prime 类并没有真正利用这一点。有人说单例模式是最被滥用的模式,他们可能是对的。

我现在只是猜测您的转换器不需要保持全局状态。按照这个假设,您可以只使用模块方法来实现您描述的 API。例如:

module MyModule
  def self.convert(data)
    MyClass.new.convert(data)
  end
end

然后你可以调用这个方法

MyModule.convert("data")

【讨论】:

好答案。我需要一些安静的时间来理解“聪明的把戏”。 现在我又想起来了,也许 Prime 类实际上在前一段时间使用了全局状态,现在他们只保留单例以实现向后兼容性。 @CarySwoveland 实际上并没有那么复杂,除了一件事。每次定义一个实例方法时,这个 sn-p 都会定义一个同名的类方法,它只是委托给单例实例。现在是困难的部分:它为此使用了Forwardable 模块,该模块用于将实例方法委托给另一个对象。但是由于我们要委托类方法,我们需要获得“更高的级别”。这是通过(class << self; self; end) 获取元类并在此使用def_delegator 而不是类本身来完成的。 元类是类的类,如果你愿意的话,它的实例方法是类的类方法。这样,委托是针对类方法而不是实例方法完成的。 感谢您的详细说明;这将使我的研究更早。一方面,我对Forwardable一无所知,但似乎值得了解。

以上是关于如何像在 Prime 类中一样在 Ruby 中创建默认实例?的主要内容,如果未能解决你的问题,请参考以下文章