[英]What is the correct way to write a singleton pattern in Ruby?
我正在尝试用Ruby编写最安全的单例。 我对这种语言很陌生,这种语言很有弹性,我没有强烈的感觉,我的单例类只能创建一个实例。 作为奖励,我希望该对象只有在真正使用时才会被实例化。
# require singleton lib
require 'singleton'
class AppConfig
# mixin the singleton module
include Singleton
# do the actual app configuration
def load_config(file)
# do your work here
puts "Application configuration file was loaded from file: #{file}"
end
end
conf1 = AppConfig.instance
conf1.load_config "/home/khelll/conf.yml"
#=>Application configuration file was loaded from file: /home/khelll/conf.yml
conf2 = AppConfig.instance
puts conf1 == conf2
#=>true
# notice the following 2 lines won’t work
AppConfig.new rescue(puts $!)
#=> new method is private
# dup won’t work
conf1.dup rescue(puts $!)
#=>private method `new’ called for AppConfig:Class
#=>can’t dup instance of singleton AppConfig
那么当你在课堂中包含单例模块时,ruby会怎么做?
new
方法变为私有,因此您无法使用它。 所以要使用ruby singleton模块,你需要两件事:
singleton
然后将其包含在所需的类中。 instance
方法获取所需的实例。 如果你想创建一个单例,为什么还要创建一个类呢? 只需创建一个对象,然后将方法和实例变量添加到所需的对象中。
>> MySingleton = Object.new
=> #<Object:0x100390318>
>> MySingleton.instance_eval do
?> @count = 0
>> def next
>> @count += 1
>> end
>> end
=> nil
>> MySingleton.next
=> 1
>> MySingleton.next
=> 2
>> MySingleton.next
=> 3
人们实现此模式的一种更标准的方法是使用Module
作为单例对象(而不是更通用的Object
):
>> module OtherSingleton
>> @index = -1
>> @colors = %w{ red green blue }
>> def self.change
>> @colors[(@index += 1) % @colors.size]
>> end
>> end
=> nil
>> OtherSingleton.change
=> "red"
>> OtherSingleton.change
=> "green"
>> OtherSingleton.change
=> "blue"
>> OtherSingleton.change
=> "red"
如果您希望单个对象从某个类继承,只需将其作为该类的实例即可。 要从mixin继承,只需使用#extend
。 如果你想要一个单例对象,ruby使它变得非常容易,而且与其他语言不同,它不必在类中定义。
Ad-hoc单身人士(我的第一个例子)到处都是,涵盖了我遇到的大多数情况。 模块技巧通常涵盖其余部分(当我想要一些更正式的东西时)。
Ruby代码应该(imho)使用duck typing(通过#respond_to?
)而不是显式检查对象的类,所以我通常不关心我的单例对象类的唯一性,因为它不是它的类使其独特,但我之后添加的一切。
require 'singleton'
class Klass
include Singleton
# ...
end
有关说明,请参阅Ruby Standard Library Singleton类文档 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.