我已经看到如何将类定义为单例(如何在ruby中创建单例):
require 'singleton'
class Example
include Singleton
end
Run Code Online (Sandbox Code Playgroud)
但是,如果我想为该单个实例提供一些参数,这意味着,示例应始终具有初始化的某些属性.例如,假设我有一个类,其唯一目的是登录文件(这只是一个示例),但它需要一个文件的名称才能在它可以工作之前登录.
class MyLogger
def initialize(file_name)
@file_name = file_name
end
end
Run Code Online (Sandbox Code Playgroud)
如何使MyLogger成为单例,但确保它获得file_name?
Jan*_*ich 15
这是另一种方法 - 将日志文件名放在类变量中:
require 'singleton'
class MyLogger
include Singleton
@@file_name = ""
def self.file_name= fn
@@file_name = fn
end
def initialize
@file_name = @@file_name
end
end
Run Code Online (Sandbox Code Playgroud)
现在你可以这样使用它:
MyLogger.file_name = "path/to/log/file"
log = MyLogger.instance # => #<MyLogger:0x000.... @file_name="path/to/log/file">
Run Code Online (Sandbox Code Playgroud)
instance即使您稍后更改了类变量的值,后续调用也将返回路径名未更改的同一对象.进一步的好处是使用另一个类变量来跟踪是否已经创建了一个实例,并且file_name=在这种情况下让该方法引发异常.initialize如果@@file_name尚未设置,您也可以引发异常.
Singleton不提供此功能,但是您可以自己编写它,而不是使用singleton
class MyLogger
@@singleton__instance__ = nil
@@singleton__mutex__ = Mutex.new
def self.instance(file_name)
return @@singleton__instance__ if @@singleton__instance__
@@singleton__mutex__.synchronize do
return @@singleton__instance__ if @@singleton__instance__
@@singleton__instance__ = new(file_name)
end
@@singleton__instance__
end
private
def initialize(file_name)
@file_name = file_name
end
private_class_method :new
end
Run Code Online (Sandbox Code Playgroud)
它应该可以工作,但我没有测试代码。
MyLogger.instance <file_name>如果您知道这将是第一次调用,此代码会强制您至少在第一次调用时使用or 。
| 归档时间: |
|
| 查看次数: |
8945 次 |
| 最近记录: |