ClassName.instance_eval 添加类方法
def add_method_to1(klass)
klass.instance_eval do
def hello
"hello!"
end
end
end
ClassName.class_eval 添加实例方法
def add_method_to2(klass)
klass.class_eval do
def hello
"hello!"
end
end
end
测试
class A
end
class B
end
add_method_to1(A)
A.hello # => "hello"
A.new.hello # => NoMethodError
add_method_to2(B)
B.hello # => NoMethodError
B.new.hello # => "hello"
-
ClassName.class_eval # 打开当前类,定义实例方法
-
ClassName.instance_eval # 打开当前类对象,定义类方法,类的单件方法
-
object.class_eval # NoMethodError
-
object.instance_eval # 在实例变量作用域中执行,在对象的上下文中执行一个块
The module_eval method is just an alias to class_eval so you can use them both for classes and modules. The instance_eval method works just like class_eval but it will add the behavior you’re trying to define to the object instance where it was called.
No, it isn’t. With class_eval we opened up a class definition and added code to it’s body. Any kind of code valid inside a class definition was also valid in there. When we’re using instance_eval the rules change a bit ‘cos we’re not opening up a class, but a single object instance.
class Dog
attribute_accessor :name
end
dog = Dog.new
dog.name = 'Fido'
dog.instance_eval do
#here I am defining a bark method only for this “dog” instance and not for the Dog class
def bark
puts 'Huf! Huf! Huf!'
end
end
other_dog = Dog.new
other_dog.name = 'Dido'
puts dog.name
puts other_dog.name
dog.bark
other_dog.bark #this line will raise a NoMethodError as there’s no “bark” method
#at this other_dog object
用法总结
instance_eval
- instance_eval 能访问对象内的实例变量和私有方法
- instance_eval 在对象的上下文中执行代码块
- 在类上调用instance_eval,创建类方法(类的单件方法, singleton_method)
- 在对象上调用instance_eval,创建对象的单件方法,singleton_method
class_eval
-
class_eval 在一个类的上下文执行字符串或代码块,功能上好像重新打开类,然后插入了一些新的代码,在类的定义中,class和end关键字之间的所有代码都可以使用
class_eval完成。 -
class_eval 作为单例方法被定义在模块类中,所以它只可以被模块或者类使用。
-
当在执行
class_eval和instance_eval方法时,变量self会被设置为接收者。
eval都用注入风险,可以使用exec替代
Resources
https://mauricio.github.io/2009/06/04/understanding-class_eval-module_eval-and-instance_eval.html
📢 In-Article Ad (Development Mode)
Comments