Ruby has the function facility to execute code saved as strings at runtime, the eval family method. Including kernel # Eval, object # instance_eval, Module # class_eval.
Kernel # eval
It is the most direct method
As follows:
1 p eval("2+2")2 3 eval("def m;p ‘hello world‘;end")4 eval("m")
Output
4
"Hello World"
Eval is powerful, dangerous, and vulnerable to code injection. Although Ruby has a global variable $ safe to control it, it is best not to use it.
Object # instance_eval
This method changes self to the receiver of the instance_eval call and evaluates the string or code block.
As follows:
1 p self2 3 a = []4 a.instance_eval {p self}
Output
Main
[]
Instance_eval is often used to access private data of other objects-especially instance variables
As follows:
1 class C2 def initialize3 @x = 14 end5 end6 7 c = C.new8 c.instance_eval {puts @x}
Output
1
Instance_eval can also accept strings to access local variables.
As follows:
1 arr = [‘a‘,‘b‘,‘c‘]2 ch = ‘d‘3 arr.instance_eval "self[1] = ch"4 p arr
Output
["A", "D", "C"]
The method defined in instance_eval is a singleton method.
As follows:
1 obj = Object.new2 3 obj.instance_eval do4 def method5 p "hello world"6 end7 end8 p obj.singleton_methods
Output
[: Method]
Module # class_eval
Class_eval is the same as module_eval. It can enter the class definition body.
1 C = Class.new2 C.class_eval do3 def method4 p "hello world"5 end6 end7 c = C.new8 c.method
Output
"Hello World"
Class_eval can do something that class keywords cannot do.
- Evaluate the string in the context of the Class Definition
- Open the class definition for an anonymous class (but does not contain a singleton class) (that is, open a class without knowing the class name)
- Get access to variables in the peripheral Scope
1 def add_method_to(a_class)2 a_class.class_eval do3 def method ; p "hello world";end4 end5 end6 add_method_to String7 "abc".method
Output
"Hello World"
1 var = "hello world"2 3 class C4 end5 C.instance_eval {puts var}
Output
"Hello World"
Summary: The instance_eval () method only changes self, while class_eval () modifies self and the current class at the same time. By modifying the current class, class_eval () actually re-opens the class, just like the class keyword.
Module # class_eval () is more flexible than the class keyword. Class keywords can only use constants, while class_eval () can use the class_eval () method for any variables that represent classes. Class opens a new scope, but class_eval () is actually a flat scope.