ruby class_eval instance_eval instance_exec

之前对这两个的用法很混淆,现在自己有仔细的思考了一下,写下来欢迎大家来探讨,给予指正。
    class_eval instance_eval 它们都继承了eval也就是Ruby的evaluation。因为class就是module的扩展,所以class_eval和module_eval我认为是一回事,class_eval是module_eval的alias。
我在这里就区分一下class_eval和instance_eval这两个让我困惑了好长时间的方法。
1.class_eval
首先它是作用在类上面的
class A
end
A.class_eval后面可以跟字符串或者block
字符串 A.class_evala(%q{def hello() "Hello word!" end})
block A.class_eval{}
我原来一直以为它是给一个类添加类方法,这是不对的,它的作用是打开一个类,给这个类添加方法(实例方法),注意添加的是实力方法。因为并没有在hello方法前加self将它变成类方法,所以他就会是实例方法。
2.instance_eval
这个使用起来很灵活,首先它是作用在实例上面的方法,我们定义的类比如
class A
@a=1
end
,其实都是class的实例,可以通过A.instance_eval{@a}来访问,或者
class B
  def initialize 
    @b= 2 
  end 
end 
 
b = B.new 
b.instance_eval { @b} #2,
如果想通过类访问它的实力变量可以这样
class A
class << self 
  attr_accessor :i
end
@i=1
end
A.i = 4 #4
A.i #4

总结一下,class_eval主要是对类做一些事情,它的职责是打开类。对类增加方法或者是include一个module等。而instance_eval关注的则是一个实例,像这样
class A
end
A.instance_eval do
  def c
  end
end
因为A本身就是class的实例,所以可以调用A.c,具体的说就是给class的实例增加一个方法,就是给A增加一个类方法。也就是说其实类方法就是class的实例类的方法。

还有instance_exec其实就是带参数的instance_eval

最后我也上个图

你可能感兴趣的:(instance)