《Ruby 元編程》讀後總結

何時須要讀這本書?

掃過一遍基本的 Ruby 語法,本身也寫過一些 Ruby 代碼,以爲 Ruby 也就是一個普通的腳本語言而已的時候。編程

這本書帶給讀者什麼東西?

在 Ruby 語法背後, Ruby 語言的構建模型。以及在這種模型下,一些可能只屬於 Ruby 的實際編程案例(也就是怎麼樣用 Ruby 的特性去簡化和優美你的代碼)閉包

那麼,元編程是什麼?

通常來講,『元xx』這樣的詞語都表示『創造 xx 的一種東西』或者『xx 背後更加原始的同樣相似的東西』,好比 iOS 開發都很熟悉的 OC 中的元類。元編程表示的是『寫出能夠編寫代碼的代碼』。函數

仍是抽象?舉一個小例子:一個類中有二十個屬性,如今你須要爲這些屬性分別創造對應的 set 方法,相似 setXXX 這樣的形式,同時要求這些 set 方法都要判斷新舊值是否一致,若是一致就直接 return。this

這樣的事情顯然是一個體力活,若是沒有好的方法,你就須要寫二十個十分相似的方法,而且每一個方法內部都差很少,只是在屬性的名稱那一部分有所區別,重複度很是高。spa

若是使用 Ruby 的元編程,當外部調用某個 set 方法(好比 setYYY)的時候,你的一段代碼就會被執行,這段代碼會動態的爲當前的類建立一個 setYYY 方法,同時代碼中能夠截斷方法名稱(也就是拿到了一個 'YYY' 字符串),經過這個名稱去動態獲取對應屬性的值(一種相似 this.get_property_by_name('YYY') 的方式),和當前 set 方法的參數進行比較,完成 set 方法的要求。整個代碼可能不超過十行,而且不重複,十分優雅。3d

應該怎樣閱讀這本書?

首先咱們來看看這本書每一章的大體內容:對象

  1. 第一章:簡單介紹了 Ruby 中面向對象的模型是怎麼實現的,同時講解了當調用一個對象的方法的時候發生了什麼事情。blog

  2. 第二章:當咱們知道方法調用是怎樣的一個流程之後,咱們就能夠考慮是否能夠攔截或者修改這個過程來實現一些黑魔法。ip

  3. 第三章:這裏話頭一轉,轉向描述 Ruby 中的代碼塊,也描述了和代碼塊息息相關的做用域的概念。作用域

  4. 第四章:這一章把話頭又轉回了類,這裏將詳細描述對象與類的組織模型,同時講解了一些和類有關的元編程方法。

  5. 第五章:着重講解 eval ,一個可以把字符串當作 Ruby 代碼解釋的函數。

  6. 第六章:休息一下,用一頁紙講個故事。

  7. 第七章-第八章:經過講解 ActiveRecord 這個強大庫的使用方法,將以前講過的魔法彙總一下。

  8. 第九章:指出一些使用元編程的注意事項、經驗教訓。

  9. 附錄:給出了一些 Ruby 中的常見事物的慣常寫法,解釋了什麼是 DSL(領域專屬語言),而後將前面講到的魔法的例子彙總了一下。

能夠看出,全書主要分兩部分,第一部分主要是 Ruby 背後的模型的講解、高級語法特性的講解,中間穿插着一些例子。第二部分則是經過解析 ActiveRecord 這個庫,將前面講到的模型的利用來了個實際展現。

所以,最好第一遍閱讀的時候着重去理解 Ruby 語言背後的模型,第二遍先看例子,本身嘗試想一想要實現這些例子經過這些模型還須要什麼東西,而後再看實際的例子。最後的附錄能夠在往後忘記一些寫法的時候翻一翻,幫助回憶。

這本書中印象深入的點?

對象與類的模型和方法調用:

  1. Ruby 中的 class 關鍵字和 Java 等語言的 class 在理解上很不一樣,Java 的 class 的做用是在全局建立一個類,而且這個類在全局只能有這一個聲明;Ruby 中 class 做用是把代碼的上下文變換到這個類中,也就是『打開類』,同一個類能夠在任何地方被打開,也所以別人的類能夠被本身隨意打開並改寫。

  2. Ruby 中的實例變量也不像 OC 或者 Java 那樣必須提早聲明,當第一次用到實例變量的時候,這個實例變量纔會生成。因此在方法裏頭看到對一個實例變量賦值的時候有多是在初始化這個實例變量。

  3. 對象中不存儲方法,只存儲屬性。對一個對象調用方法的時候,會首先去這個對象的 singlenton class 中找,而後去 singleton class 的父類中(實例對象的 singleton class 的父類是這個實例對象的類,類的 singleton class 的父類是這個類的父類的 singleton class ,類也是對象,不過特殊在類這個對象只有一個)。當調用方法的時候,首先去這個對象的 singleton class 中查找,沒有的話繼續向 singleton class 的父類查找,在以下完整的對象與類的結構圖中能夠簡單記成『向右一步,而後向上』。enter image description here

  4. 定義類方法其實就是向類的 singleton class 中添加新的方法。

  5. 除了使用點語法調用方法,還可使用 send 方法來調用方法,這樣就可使用字符串拼出來的方法名來調用方法了。(經過 send 甚至能夠在外部調用類的私有方法)

  6. 可使用 define_method 來建立方法,和 def 的區別在於,define_method 後面能夠是一個變量。

  7. method_missing 這個方法也能夠動態增長方法。注意用這種方式的時候也要重寫 respond_to? 方法。

  8. 模塊有一個 included 的類方法,在這個模塊被 include 的調用,咱們能夠在裏頭寫上自動增長類方法的代碼,這樣一個模塊被 include 了之後,不止增長了實例方法,還增長了類方法,這個叫作類擴展混入(Class Extension Mixin)

  9. 一樣一個 @a ,聲明在類的做用域中和類的方法的做用域中是不同的。前者是類對象的實例變量,後者的類的實例對象的實例變量。

Block: 與 做用域

  1. 任何方法均可以傳入一個 block ,不過有的方法會不處理 block ,此時傳入 block 什麼用也沒有。

  2. 一個做用域能夠理解爲一個上下文環境,在同一個做用域中的代碼能夠互相訪問彼此的變量。當有 class/def/module 的時候,代碼會進入一個新的做用域,而且做用域之間並無什麼關係,也就是說內部做用域不會獲得外部做用域的變量(除了全局變量,全局變量是能夠在任何做用域中獲得的)。

  3. 可使用 block 利用閉包在不一樣做用域之間傳遞變量。

  4. block 都是待着做用域的,也就是說 block 這個『行爲』帶着這個行爲建立時的『數據』。

  5. 經過 method(:method_name) 能夠獲得一個 method 對象,不過 method 對象必須綁定到一個對象上才能被調用。

相關文章
相關標籤/搜索