class_eval 和 instance_eval的区别

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,所以当类(类也是对象)直接调用该方法是,实际上定义的是类方法,如下面的代码 ```Ruby 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
```Ruby
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,前提是调用为类或是模块

posted @ 2017-02-27 18:55  chzhzh  阅读(265)  评论(0编辑  收藏  举报