classC;end class << C # 类方法 deff1 puts "in C's singleton_class" end # C的单例类对象的单例方法,即进入了C的单例类的单例类 defself.f2 puts "singtleton_class of C's singleton_class" end end
classC class << self defcreate_method(name, &block) # self是C类对象自身 # 进入C的单例类,define_method定义的是C的类方法 self.singleton_class.define_method(name, &block) end end end C.create_method(:f) {puts "f"} C.f
defc.singleton_method_added(meth) case meth when:singleton_method_added, :singleton_method_removed, :singleton_method_undefined return end puts "Adding singleton_method: #{meth}" end
p D.singleton_class.superclass.superclass.superclass p D.singleton_class.superclass.superclass.superclass.superclass p D.singleton_class.superclass.superclass.superclass.class =begin #<Class:BasicObject> Class Class =end
moduleSingleton # 禁用对象的实例方法clone、dup # Raises a TypeError to prevent cloning. defclone raise TypeError, "can't clone instance of singleton #{self.class}" end # Raises a TypeError to prevent duping. defdup raise TypeError, "can't dup instance of singleton #{self.class}" end # By default, do not retain any state when marshalling. def_dump(depth = -1) '' end # 下面这些方法将通过extend的方式扩展到类对象中,即作为类方法 # 定义在一个子模块中,主要是为了封装多个方法 moduleSingletonClassMethods# :nodoc: defclone# :nodoc: Singleton.__init__(super) end # By default calls instance(). Override to retain singleton state. def_load(str) instance end private definherited(sub_klass) super Singleton.__init__(sub_klass) end end # 设置模块环境:定义模块方法__init__ # 将在included时被调用(klass是目标类),于是instance()被声明了 class << Singleton # :nodoc: def__init__(klass)# :nodoc: klass.instance_eval { # 初始化一个类对象的实例变量用于保存唯一的单例对象 @singleton__instance__ = nil @singleton__mutex__ = Thread::Mutex.new } def klass.instance # :nodoc: # 如果单例对象已存在,直接返回 return @singleton__instance__ if @singleton__instance__ # 否则,创建单例对象,且某一时刻只允许一个线程创建,否则线程不安全 @singleton__mutex__.synchronize { return @singleton__instance__ if @singleton__instance__ @singleton__instance__ = new() } @singleton__instance__ end klass end private # 移除extend Singleton模块的扩展方式 # extending an object with Singleton is a bad idea undef_method :extend_object def append_features(mod) # help out people counting on transitive mixins unless mod.instance_of?(Class) raise TypeError, "Inclusion of the OO-Singleton moduleinmodule#{mod}" end super end defincluded(klass) super klass.private_class_method :new, :allocate# 私有化类方法.new和.allocate klass.extend SingletonClassMethods Singleton.__init__(klass) end end ## # :singleton-method: _load # By default calls instance(). Override to retain singleton state. end