1 Kernel#eval() , 它不是使用块,而是直接使用包含Ruby代码的字符串--简称为代码字符串.
Kernel#eval()方法会执行字符串中的代码,并返回执行结果:
1 array = [10,20] 2 element = 30 3 eval("array<<element") #=>[10,20,30]
2 Binding就是一个用对象表示的完整作用域.可以通过创建Binding对象来捕获并带走当前的作用域.接下来,可以通过eval()方法,instance_eval()方法或class_eval()方法,在Binding对象所携带的作用域中执行代码.
可以使用Kernel#binding()方法来创建Binding对象:
1 class MyClass 2 def my_method 3 @x = 1 4 binding 5 end 6 end 7 8 b = MyClass.new.my_method 9 @x = 5 10 puts eval "@x" ,b #=> 1
3 eval()方法总是需要一个代码字符串作为参数,而instance_eval()方法和class_eval()方法除了块,也可以接受代码字符串作为参数,但是能用块就尽量用块.
4 因为涉及到安全问题,所以最好禁用eval()方法.
5 可以用$SAFE全局变量设置安全级别(0-4).当安全级别大于0时,ruby会拒绝执行污染的字符串.
6 有两个方法可以操作实例变量:Object#instance_variable_get()方法和Object#instance_variable_set()方法.
7 钩子方法
1 class String 2 def self.inherited(subclass) 3 puts "#{self} was inherited by #{subclass}" 4 end 5 end 6 class MyString < String ;end #=> String was inherited by MyString
inherited()方法是Class的一个实例方法,当类被继承时,Ruby会调用这个方法.像Class#inherited()这样的方法称为钩子方法,因为可以用它们像钩子一样钩住一个特定的事件.
8 常用的钩子方法: Module#included() ; Module#extend_object(); Module#method_added(); Module#method_removed() ; Module#method_undefined()方法.
9 类扩展混入:
(1) 定义一个模块,例如MyMixin.
(2) 在MyMinxin中定义一个内部模块(例如ClassMethods),并给它定义一些方法.这些方法最终会成为类方法.
(3) 覆写MyMixin#included()方法来用ClassMethods扩展包含者(使用extend()方法)
例:
1 module MyMixin 2 def self.included(base) 3 base.extend(ClassMethods) 4 end 5 module ClassMethods 6 def x 7 "x()" 8 end 9 end 10 end
可以在MyMixin中(但是在子模块ClassMethods的外部)直接定义一些额外的方法.这些方法将会成为包含者的实例方法.通过这种方式,可以通过包含一个模块来同时得到新的实例方法和类方法.