在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
ruby具有在运行时执行以字符串形式保存的代码的功能设施,eval族方法 。包括Kernel#eval,Object#instance_eval,Module#class_eval。 Kernel#eval 它是最直接的方法 如下: 1 p eval("2+2") 2 3 eval("def m;p 'hello world';end") 4 eval("m") 输出 4 eval强大而危险,有代码注入之类的危险,尽管ruby中有一个全局变量$SAFE来控制它,但最好还是不要用它。
Object#instance_eval 该方法将self变为instance_eval调用的接收者,对字符串或者代码块求值。 如下: 1 p self 2 3 a = [] 4 a.instance_eval {p self} 输出 main instance_eval常常用于访问其他对象的私有数据--特别是实例变量 如下: 1 class C 2 def initialize 3 @x = 1 4 end 5 end 6 7 c = C.new 8 c.instance_eval {puts @x} 输出 1 instance_eval也可以接受字符串,访问局部变量。 如下: 1 arr = ['a','b','c'] 2 ch = 'd' 3 arr.instance_eval "self[1] = ch" 4 p arr 输出 ["a", "d", "c"]
instance_eval中定义方法,则会是个单例方法 如下: 1 obj = Object.new 2 3 obj.instance_eval do 4 def method 5 p "hello world" 6 end 7 end 8 p obj.singleton_methods 输出 [:method]
Module#class_eval class_eval和module_eval是一样的。它可以进入类定义体内。 1 C = Class.new 2 C.class_eval do 3 def method 4 p "hello world" 5 end 6 end 7 c = C.new 8 c.method 输出 "hello world"
class_eval可以做一些class关键字不能做的事
1 def add_method_to(a_class) 2 a_class.class_eval do 3 def method ; p "hello world";end 4 end 5 end 6 add_method_to String 7 "abc".method 输出 "hello world"
1 var = "hello world" 2 3 class C 4 end 5 C.instance_eval {puts var} 输出 "hello world"
总结:instance_eval()方法仅仅会改变self ,而 class_eval()会同时修改self和当前类,通过修改当前类,class_eval()实际上是重新打开了该类,就像class关键字一样。 Module#class_eval()比class关键字更加灵活,class关键字只能使用常量,而class_eval()可以对任何代表类的变量使用class_eval()方法。class会打开一个新的作用域,但是class_eval()其实是扁平化作用域。
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论