<Ruby>元编程第五章笔记

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的外部)直接定义一些额外的方法.这些方法将会成为包含者的实例方法.通过这种方式,可以通过包含一个模块来同时得到新的实例方法和类方法.

posted on 2014-03-12 18:19  秋叶leaf  阅读(291)  评论(0)    收藏  举报