3-15 《元編程》第6章 3-16 hook method

Code That Writes Code?

6.1 Coding your way to the weekend

?

6.2 Kernel#eval, Binding#eval?

Binding:

Objects of class?Binding(類Binding的對象)?encapsulate (密封)the execution context at some particular place in the code and retain this context for future use.

?

如果你想要一段已經執行的代碼在今后反復使用,可以用Binding對象封裝它。

The variables, methods, value of?self, and possibly an iterator block(迭代塊) that can be accessed in this context are all retained.?

變量,方法,自身的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.

?

class Myclass
? def my_method
? ? @x = 1
? binding
? end
end
p b = Myclass.new.my_method
p b.eval("@x")
p eval("@x", b)

#結果一樣 1

?

class Anotherclass
? def my_method
? ? # eval "self", TOPLEVEL_BINDING? ?#=> main
? ? eval("xx + yy", TOPLEVEL_BINDING)
? end
end
xx = 123
yy = 321
obj = Anotherclass.new
p obj.my_method #=> 444

TOPLEVEL_BINDING: 是預定義常量,表示頂層作用域的Binding對象。

?

6.24 Strings of Code Vs Blocks?

?eval只能執行代碼字符串,instance_eval和class_eval可以執行代碼字符串和block

array = [1,2,3]
x = 'd'
array.instance_eval("self[1] = x")
p array #=> [1, "d", 3]
盡量用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...

?

這種鉤子方法寫在模塊里,用類方法的方式定義:

module M1
? def self.included(othermod)
? ? puts "m1 was included into #{othermod}"
? end
end
class C
? include M1
end
#=>m1 was included into C

另外一種方式鉤住同一個事件,:#include方法可以覆寫 ,但注意寫在類C中。

我的理解類C.調用include方法,就是self.include。先是在自身調用覆寫的include方法,然后用super關鍵字調用原始方法。

?? 類方法是不能被繼承的只能自己用。

?? 類包含模塊后默認是獲得實例方法。除非用#extend

module M
? def hello
? ? puts "world"
? end
end
class C
? def self.include(mod)
? ? puts "Called: C.include(#{mod})"
? ? super? #因為覆寫了include,所以需要用super調用原始的include功能,否則M不會被C包含
? end?
? include(M)
end
C.new.hello?

?類方法和鉤子方法結合的技巧:P160頁。?

轉載于:https://www.cnblogs.com/chentianwei/p/8574545.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/250793.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/250793.shtml
英文地址,請注明出處:http://en.pswp.cn/news/250793.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

7 useLayoutEffect、useDebugValue

useEffect:dom完成渲染后執行 不傳參數,每次都會執行 傳空的依賴[],只會執行一次 有依賴,依賴項變化會執行 useEffect實現動畫效果 import { useEffect, useRef, useState } from "react"const App () > {const [,…

【Linux】用戶與權限

追加用戶組 groupadd 用戶組名 追加新用戶 useradd -d 指定用戶目錄 -s 指定用戶使用shell -g 指定用戶組 -p 指定用戶密碼 用戶名 更改用戶 添加用戶到其他組 usermod -G 用戶組 用戶名 修改用戶密碼 passwd 用戶名 刪除用戶 userdel [參數] 用戶名參數:-f&#x…

es6 --- map的使用

思路: 1.使用一個map數組來保存nums1中出現的元素及其次數. 2.遍歷nums2.使用map的has方法來檢測nums2中的元素是否出現在map中,若出現則加入返回數組(retArr),且map數組中的次數減1 /*** param {number[]} nums1* param {number[]} nums2* return {number[]}*/ var intersect…

NOIP2005普及組第3題 采藥 (背包問題)

NOIP2005普及組第3題 采藥    時間限制: 1 Sec 內存限制: 128 MB提交: 50 解決: 23[提交][狀態][討論版][命題人:外部導入]題目描述 辰辰是個天資聰穎的孩子,他的夢想是成為世界上最偉大的醫師。為此,他想拜附近最有威望的醫師為師。醫師為了判斷他…

前端面試之Vue相關總結

Vue2中檢測數組變化的限制和解決方法 vue2用下標設置數組沒效果 arr [1,2] arr[0] 0,頁面上顯示的arr并沒有修改(如果對應下標是原始值;若是引用值)解決1:Vue.Set解決2:arr.splice (Vue會劫持splice方法) Vue2對對象是循環defineProperty…

JS和安卓 IOS的交互 例子式記錄

(function () { var u navigator.userAgent; var isAndroid u.indexOf(Android) > -1 || u.indexOf(Adr) > -1; //android終端 var isiOS !!u.match(/\(i[^;];( U;)? CPU.Mac OS X/); if(isAndroid){ (function(){ function android_i…

vue --- ref屬性獲取dom元素和子組件的方法

說明: // 假設login的組件定義如下: Vue.component(login, {template:<h1>登錄</h1>,data(){return {msg:son msg,}},methods(){show(){console.log(調用子組件的方法);}} }) // 在父元素中使用 <div id"app"><login ref"myLogin"&g…

【工程師綜合項目二】React + Koa2打造『JS++官網管理后臺』

Redis認知、安裝與操作 MongoDB&#xff1a;動態數據庫&#xff0c;如游戲中需要頻繁地保存人物的坐標 Oracle&#xff1a;收費&#xff0c;企業級 mac要安裝homebrew&#xff08;包管理工具&#xff09; window安裝Redis程序運行教程 命令行Redis操作 啟動&#xff1a; redis-…

webpack --- html-webpack-plugin

安裝 cnpm i html-webpack-plugin -D配置 (webpack.config.js) // webpack 是基于node構建的,webpack的配置文件中,任何合法的Node代碼都是支持的 var path require(path)// 在內存中生成src下的index.html,同時自動將打包好的bundle.js 導入到頁面中 var htmlWebpackPlugin…

nyoj164——卡特蘭數(待填坑)

題意&#xff1a;將1~2n個數按照順時針排列好&#xff0c;用一條線將兩個數字連接起來要求&#xff1a;線之間不能有交點&#xff0c;同一個點只允許被連一次。 最后問給出一個n&#xff0c;有多少種方式滿足條件。 卡特蘭數&#xff08;列&#xff09;&#xff1a; 令h(0)1,h(…

git 使用

1. 先進入項目文件夾&#xff0c;通過命令 git init 把這個目錄變成git可以管理的倉庫 git init 2. 把文件添加到版本庫中&#xff0c;使用命令 git add .添加到暫存區里面去&#xff0c;不要忘記后面的小數點“.”&#xff0c;意為添加文件夾下的所有文件 git add . 3. 用命令…

webpack --- 使用vue

// webpack中如何使用 vue: // 1. 安裝vue 的包: cnpm i vue -S // 2. 由于在 webpack 中,推薦使用 . vue 這個組件模板文件定義組件, 所以需要安裝能解析這種文件的loader cnpm i vue-loader vue-template-compiler -D // 3. 在main.js 中導入 vue的包, import Vue from vue…

ES6雜碎

1、let聲明的變量沒有變量提升&#xff1b; 2、const聲明的變量&#xff1a;塊級作用域內有效&#xff0c;存在暫時性死區&#xff0c;變量指向的那個內存地址不得改動&#xff1b; 3、...tail解構出來的是數組或空數組 let [head, ...tail] [1, 2, 3, 4]; head //1 tail //[2…

koa --- 自制簡易的koa-router

打算自己寫一個簡單的Router類,來實現koa-router這個中間件的(部分)神奇功能 確定需求 1.首先導入需要在app.js里面導入自己寫的Router類 2.然后是使用的方式和掛載router的方式 // 導入Router類 const Router require(./components/router.js);// 使用方式,(暫時只對get請…

MariaDB 腳本

研究MariaDB&#xff0c; 需要mock up一些假數據&#xff1a; 生成n個長度整型數的函數rand_num&#xff1a; CREATE DEFINERrootlocalhost FUNCTION rand_num(n INT) RETURNS int(5) begin DECLARE i INT DEFAULT 0; DECLARE result INT DEFAULT 0; WHILE i < n DOSET re…

Promise的基本使用

利用Promise是解決JS異步執行時候回調函數嵌套回調函數的問題&#xff0c; 更簡潔地控制函數執行流程&#xff1b; 通過new實例化Promise&#xff0c; 構造函數需要兩個參數&#xff0c; 第一個參數為函數執行成功以后執行的函數resolve&#xff0c; 第二個函數為函數執行失敗…

軟工作業PSP與單元測試訓練

一、實現模塊判斷傳入的身份證號碼的正確性&#xff1b; 二、針對所實現的模塊編寫對應的單元測試代碼&#xff1b; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; import java.u…

koa --- nunjucks

安裝: npm install koa-nunjucks-2 --save目錄結構 |--- controller/ | |--- home.js |--- service/ | |--- home.js |--- views/ |--- app.js |--- router.jsapp.js // (部分) const nunjucks require(koa-nunjucks-2); app.use(nunjucks({ext: html,path: path.joi…

DNN模型訓練詞向量原理

轉自&#xff1a;https://blog.csdn.net/fendouaini/article/details/79821852 1 詞向量 在NLP里&#xff0c;最細的粒度是詞語&#xff0c;由詞語再組成句子&#xff0c;段落&#xff0c;文章。所以處理NLP問題時&#xff0c;怎么合理的表示詞語就成了NLP領域中最先需要解決的…

天平稱重【遞歸解法】

用天平稱重時&#xff0c;我們希望用盡可能少的砝碼組合稱出盡可能多的重量。如果只有5個砝碼&#xff0c;重量分別是1&#xff0c;3&#xff0c;9&#xff0c;27&#xff0c;81則它們可以組合稱出1到121之間任意整數重量&#xff08;砝碼允許放在左右兩個盤中&#xff09;。 本…