digging ruby: instance_eval and class_eval
最近编程的时候,使用了不少的ruby metaprogramming的方法。但是有些问题总是没有搞清楚,特别是对于instance_eval和class_eval的用法,总是有些迷糊。今天查了一些资料,又在stackoverflow上问了一些问题,现在总结一下。
instance_eval
首先从名字可以得到的信息是,instance_eval的调用者receiver必须是一个实例instance,而在instance_eval block的内部,self即为receiver实例本身。
obj_instance.instance_eval do self # => obj_instance # current class => obj_instance's singleton classend
根据这个定义,如果在一个实例上调用了instance_eval,就可以在其中定义该实例的单态函数 singleton_method
class Aenda = A.newa.instance_eval do self # => a # current class => a's singleton class def method1 puts 'this is a singleton method of instance a' endenda.method1#=> this is a singleton method of instance ab = A.newb.method1#=>NoMethodError: undefined method `method1' for #
同样,因为类class本身也是Class类的一个实例,instance_eval也可以用在类上,这个时候就可以在其中定义该类的singleton_method,即为该类的类函数。
换句话说,可以用instance_eval来定义类函数class method,这比较容易混淆,需要搞清楚。
class AendA.instance_eval do self # => A # current class => A's singleton class def method1 puts 'this is a singleton method of class A' endendA.method1#=> this is a singleton method of class A
class_eval
再来看class_eval,首先从名字可以得到的信息是,class_eval的调用者receiver必须是一个类,而在class_eval block的内部,self即为receiver类本身。
class AendA.class_eval do self # => A # current class => Aend
根据这个定义,如果在一个类上调用了class_eval,就可以在其中定义该类的实例函数 instance_method
class Aenda = A.newa.method1#=> NoMethodError: undefined method `method1' for #A.class_eval do self # => A # current class => A def method1 puts 'this is a instance method of class A' endenda.method1#=> this is a instance method of class A
换句话说,可以用class_eval来定义实例函数instance method,这也比较容易混淆,需要搞清楚。
总结
instance_eval必须由instance来调用,可以用来定义单态函数singleton_methods
class_eval必须是由class来调用,可以用来定义实例函数instance_methods
参考:instance_eval vs class_eval in ruby [1] [2]














