这一次,让我们搞一些破坏性实验,来验证上两次的内容
第一个破坏性实验,module里定义self.xxx方法
ruby 代码
- irb(main):001:0> module M
- irb(main):002:1> def self.method_with_self
- irb(main):003:2> end
- irb(main):004:1> end
- => nil
- irb(main):005:0> class A
- irb(main):006:1> include M
- irb(main):007:1> end
- => A
- irb(main):008:0> A.methods - Class.methods
- => [] #空的,你能想到为什么么?
让我仔细看看,我们定义的方法呢?
ruby 代码
- irb(main):009:0> M.singleton_methods
- => ["method_with_self"] #原来跑到M的单例类里面去了,别忘了,module也是Class
ruby 代码
- irb(main):010:0> class B
- irb(main):011:1> end
- => nil
- irb(main):012:0> B.extend M
- => B
- irb(main):013:0> B.ancestors
- => [B, Object, Kernel]
ok,再来让我们看看B的单例类此时发生了什么变化
ruby 代码
- irb(main):014:0> singleton_class_of_b = class<<B;self;end
- => #<Class:B>
- irb(main):015:0> singleton_class_of_b.ancestors
- => [M, Class, Module, Object, Kernel] #正如我们预料的,M变成了B单例类的直接父类
正如预料的,M变成了B单例类的直接父类,M中定义的实例方法,变成了B的类方法(因为M中的实例方法被B的单件类继承,变成了单件类的实例方法,也就是B的类方法),M中定义的以self开头的类方法呢?当然仍然在M的单件类里面啦,它是不会随着M插入点的变化而变化的。
第二个破坏性实验,单件类中的self.xxx方法?
ruby 代码
- irb(main):001:0> class A
- irb(main):002:1> end
- => nil
- irb(main):003:0> class<<A
- irb(main):004:1> def self.method_defined_in_singleton_class_of_a
- irb(main):005:2> end
- irb(main):006:1> end
- => nil
- irb(main):007:0> A.singleton_methods
- => [] #看来定义的singleton方法并不属于A
- irb(main):008:0> singleton_class_of_a = class<<A;self;end
- => #<Class:A> #A的单件类
- irb(main):009:0> singleton_class_of_a.singleton_methods
- => ["method_defined_in_singleton_class_of_a", "new", "nesting"]
- #原来变成了A的单件类的singleton方法
看了上面代码后想想其实很自然,我们之前说过“所有的类方法都是放在这个类对象的单例类中”,所以,我们新建的这个方法method_defined_in_singleton_class_of_a实际上是放到了A的singleton class <A>的singleton class<A<A>>中的。
第三个破坏性实验,找不到直接父类M?
ruby 代码
- irb(main):001:0> module M
- irb(main):002:1> def self.class_method_defined_in_m
- irb(main):003:2> puts "singleton method in m"
- irb(main):004:2> end
- irb(main):005:1> end
- => nil
- irb(main):006:0> class A
- irb(main):007:1> include M
- irb(main):008:1> end
- => A
- irb(main):009:0> A.ancestors
- => [A, M, Object, Kernel]
- irb(main):010:0> A.superclass
- => Object