class C;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
class C 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
单例类的祖先链
对于类或模块来说,有祖先链的概念,某个类或模块的祖先链可通过ancestors()方法查看:
1 2 3 4
class C;end class D < C;end p D.ancestors #=> [D, C, Object, Kernel, BasicObject]
class C;end class << C;end class D < C;end class << D;end p D.singleton_class.ancestors =begin [#<Class:D>, #<Class:C>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject] =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
class C # 将new()私有化,不允许外界创建实例 # 提供类方法instance()来创建唯一的实例对象 # 并使用类实例变量@instance保存唯一的实例对象 class << self private:new definstance @instance = @instance ? @instance : new("Admin") end end
definitialize name @name = name end end
c1 = C.instance c2 = C.instance p c1 p c2 p c1 === c2 =begin #<C:0x0000000005189570 @name="Admin"> #<C:0x0000000005189570 @name="Admin"> true =end
moduleSingleton # 禁用对象的实例方法clone、dup # Raises a TypeError to prevent cloning. defclone raiseTypeError, "can't clone instance of singleton #{self.class}" end
# Raises a TypeError to prevent duping. defdup raiseTypeError, "can't dup instance of singleton #{self.class}" end
# By default, do not retain any state when marshalling. def_dump(depth = -1) '' end
# 移除extend Singleton模块的扩展方式 # extending an object with Singleton is a bad idea undef_method :extend_object
defappend_features(mod) # help out people counting on transitive mixins unless mod.instance_of?(Class) raiseTypeError, "Inclusion of the OO-Singleton module in module #{mod}" end super end
defincluded(klass) super klass.private_class_method :new, :allocate# 私有化类方法.new和.allocate klass.extendSingletonClassMethods Singleton.__init__(klass) end end
## # :singleton-method: _load # By default calls instance(). Override to retain singleton state. end