如何像在 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 中创建默认实例?的主要内容,如果未能解决你的问题,请参考以下文章

如何仅通过提供大小来像在 Java 中一样在 Kotlin 中创建数组?

如何像在 Eclipse 中一样在 IntelliJ 中创建可运行的 JAR

如何像在 Eclipse 中一样在 IntelliJ 中创建可运行的 JAR

如何在php中创建SOAP请求,就像在SoapUI中一样?

我们可以像在 Hive 中一样在 Big Query 中创建动态分区吗?

像在 ICS 中一样在 android 2.x 中创建下拉菜单的最佳方法