class_eval 和 instance_eval的区别

时间:2021-10-10 19:01:27

instance_eval class_eval 的区别

instance_eval

class GrandFather
def initialize
@name = "ry"
end
end

father = GrandFather.new
name = "alias"

father.instance_eval do
p self #=> #<GrandFather:0x0000000b4c2ba0 @name="ry">
p @name #=> "ry"
p name #=> "alias"

def wife
p "a beauty"
end
end

father.wife #=> "a beauty"


1、p self可以看出通过instance_eval访问到该类实例方法
2、block是一个闭包,既能访问name,又能访问@name,这种方式叫上下文探针,即深入到对象中的代码片段,对其进行操作
3、由于instance_eval中的self为当期的对象,根据作用域的定义(def class module区分作用域),所以在
instance_eval中定义的方法为单件方法,只有该obj可以访问得到
4、调用者必须为一个实例
5、因为instance_eval改变当前的接受着为self,所以当类(类也是对象)直接调用该方法是,实际上定义的是类方法,如下面的代码

class GrandFather
def initialize
@name = "ry"
end
end

GrandFather.instance_eval do
def wife
p "she is my grandmother"
end
end

p GrandFather.wife #=>"she is my grandmother"

calss_eval

注:class_eval 别名是 module_eval

class GrandFather
end

GrandFather.class_eval do
p self #=> 类本身

def feature
p self #=> 实例
@appearance = "handsome"
end
end

GrandFather.new.feature


class_eval 相当于打开类,定义类的实例方法

最后:

1、定义单件方法或是类方法,可以用instance_eval,前提是调用为对象(类也是对象)
2、定义类的实例方法,用class_eval,前提是调用为类或是模块