我正在尝试将调用包装到类中的单例中(因为我不希望其余代码知道它们正在与单例进行通信),并且我查看了委托模块。
在我的代码中,我有类似的东西:
class HideSingleton
@@obj = SingletonClass.instance # x is an instance of SingletonClass
# I want to be able to say HideSingleton.blah,
# where 'blah' is instance method of SingletonClass instance (i.e., 'x')
SimpleDelegator.new @@obj.field
end
class SingletonClass < BaseClass
attr_reader :field
def initialize
@field = SimpleDelegator.new super(BaseClass Constructor params)
end
end
然后在irb:
> require 'singleton_class'
> x = SingletonClass.new
> x.blah # 'blah' is a method that is present in BaseClass instance
> require 'hide_singleton'
> y = HideSingleton
我该怎样做y.blah
?
答案 0 :(得分:1)
我认为您尝试执行的操作更简单,但要完成委托给单例类的隐藏单例类,您可以执行以下操作:
require 'delegate'
require 'forwardable'
class BaseClass
def blah
puts 'hi'
end
end
class SingletonClass < BaseClass
attr_reader :field
def initialize
@field = SimpleDelegator.new(BaseClass.new)
end
end
class HideSingleton
def self.obj
@@obj ||= SingletonClass.new.field
end
def self.method_missing *args
obj.send *args
end
end
然后您可以进行以下调用:
x = SingletonClass.new
x.blah
hi
=> nil
HideSingleton.blah
hi
=> nil
答案 1 :(得分:0)
有一些问题需要注意:
HideSingleton类本身仍然有几个方法(来自Object和Module),这些方法将在HideSingleton上调用,而不是在SingletonClass上调用。例如,如果我们在类中有不同的常量:
class SingletonClass < BaseClass
SingletonConst = :foo
end
class HideSingleton
HideConst = :bar
end
然后在两个类上调用类方法常量会导致:
SingletonClass.constants
#=> [:SingletonConst]
HideSingleton.constants
#=> [:HideConst]
任何标准方法(const_get,class_eval,dup,respond_to?等)都是如此。为避免这种情况,您需要卸载要传递给SingletonClass的HideSingleton中的方法(或显式转发它们)。