Code That Writes Code 程序員
6.1 Coding your way to the weekendexpress
6.2 Kernel#eval, Binding#eval 安全
Binding:this
Objects of class Binding(類Binding的對象)
encapsulate (密封)the execution context at some particular place in the code and retain this context for future use.lua
若是你想要一段已經執行的代碼在從此反覆使用,能夠用Binding對象封裝它。spa
The variables, methods, value of self
, and possibly an iterator block(迭代塊) that can be accessed in this context are all retained. code
變量,方法,自身的value,甚至迭代塊均可以用Binding對象封裝儲存。對象
Binding objects can be created using Kernel#binding
繼承
eval(string [, filename [,lineno]]) → obj事件
Evaluates the Ruby expression(s) in string, in the binding's context.
Binding對象的eval方法,能夠評估字符串內的Ruby表達式,並返回表達式的值。
If the optional filename and lineno parameters are present, they will be used when reporting syntax errors.
#結果同樣 1
TOPLEVEL_BINDING: 是預約義常量,表示頂層做用域的Binding對象。
6.24 Strings of Code Vs Blocks
eval只能執行代碼字符串,instance_eval和class_eval能夠執行代碼字符串和block
流行的作法是禁止使用eval方法,同時用Dynamic methods和Dynamic Dispatch替代
污染對象
Ruby把外部傳入的對象標記爲污染對象。Object#taint -> obj.
判斷: #tainted? ->true/false
去掉污染 #untaint
謹慎使用安全級別p148頁
可使用proc {}.call 做爲潔淨室
6.3Hook Method:
Class#inherited是一個實例方法,當一個類被繼承時,Ruby會調用這個方法,Class#inherited方法什麼也不作,但程序員能夠覆寫它的行爲,像這樣的方法稱爲鉤子方法。
inherited(subclass):Callback invoked whenever a subclass of the current class is created.
更多的鉤子方法:
Module#included,#prepended,#method_added, #method_removed, #method_undefined (只對實例方法有用),#singleton_method_added...
這種鉤子方法寫在模塊裏,用類方法的方式定義:
另一種方式鉤住同一個事件,:#include方法能夠覆寫 ,但注意寫在類C中。
個人理解類C.調用include方法,就是self.include。先是在自身調用覆寫的include方法,而後用super關鍵字調用原始方法。
⚠️ 類方法是不能被繼承的只能本身用。
⚠️ 類包含模塊後默認是得到實例方法。除非用#extend
類方法和鉤子方法結合的技巧:P160頁。