使用include,让模块中定义的方法分别插入类方法与实例方法
# =============================
# 目标1:
# 1、类扩展:使用include,让模块中定义的方法分别插入类方法与实例方法中
# 2、obj实例对象调用extend,则模块中定义的方法为?
# 3、在模块中定义的实例变量能否被包含它的类的实例对象看到
# =============================
# 结论
# 1、通过重定义横块中的self.included方法,并对参数(receiver),使用关键字extend/include,分别向包含它的类中插入了
# 类方法(定义在ClassMethods模块中的方法)和实例方法(定义在InstanceMethod模块中)
# 2、obj实例对象调用extend,则模块中定义的方法为这个obj的单例方法,可以通过把方法定义在module中,让实例对象调用extend
# 来方便快速的增加自身的单例方法
# 3、可以。在模块中定义的实例变量可以被包含它的类的实例对象看到,因为被include的模块相当于当前类的父类,当前对象的
# 实例变量对其所有实例方法可见
# 4、extend方法的实质就是把module中定义的方法插入到对象的单件类中
# 5、调用MyClass.instance_methods(false)可以发现,在它的实例方法中并不包含实例方法instance_method,而MyClass
# 的实例对象可以调用这个方法,这正说明了类中include的模块(被代理类封装)充当这个类的父类。也验证了结论4
# =============================
lambda {
module M
module ClassMethods
def class_method
"i am a class method"
end
end
module InstanceMethods
def instance_method(from)
@instance_variate = "i am a instance variate in M"
"i am a instance method from:#{from}"
end
end
def self.included(receiver)
receiver.extend ClassMethods
receiver.send :include, InstanceMethods
end
end
#<!-- more -->
class MyClass
include M
def get_instance_variate_from_module(from)
"#{@instance_variate} from: #{from}"
end
end
obj = Object.new
obj.extend M::InstanceMethods
my = MyClass.new
puts "================test1 OUTPUT================"
puts MyClass.class_method
puts my.instance_method("MyClass.new obj")
puts my.get_instance_variate_from_module("MyClass.new")
puts obj.instance_method("Object.new")
puts obj.instance_eval("@instance_variate")
puts "MyClass.instance_methods:"+MyClass.instance_methods(false).to_s
puts "================test1 OUTPUT================"
# ================test1 OUTPUT================
# i am a class method
# i am a instance method from:MyClass.new obj
# i am a instance variate in M from: MyClass.new
# i am a instance method from:Object.new
# i am a instance variate in M
# MyClass.instance_methods:[:get_instance_variate_from_module]
# ================test1 OUTPUT================
}.call