《Ruby 元編程》——十年來讀到的最好的編程技術書籍

遠超預期的驚喜

在出行前的一天拿到這本書,翻了幾頁,感覺不錯,心裏很有些糾結。要出遠門的原因,衣物和工作設備之外的東西要儘量精簡。 書籍方面反覆挑揀,正在讀和很想讀的幾本書,也都只好先放下,最後帶上了這本新書和一本工作用書。

在飛機上拿起這本書後,一邊讀,一邊用筆勾劃記錄,三小時的班程,一氣讀完了半本。 然後在大巴、城鐵和地鐵上,一直到放下行李,閱讀到半夜,翻到附錄C結束,才滿足的放下。

這麼多年來,只有三本書給過我這樣的體驗:編碼的奧祕、《設計模式》(GOF),和這本 Ruby元編程。 如果考慮編碼的奧祕不算技術書籍(科普或教育類),那麼本書和《設計模式》是僅有的兩本。

動態語言的《設計模式》

事實上,我不是 Ruby 程序員,也不是 Ruby 語言的愛好者,甚至不算是 Ruby 語言的用戶。 我是有十年學習經歷的 Python 愛好者,前 C# 、 CPP 、 Delphi 程序員、 現在是專業的 Objeictive C 工程師。 在讀到本書之前,Ruby 對我來說,是一個有趣,但是沒有足夠的興趣去深入的技術。

這本書和 《設計模式》 的一個共同之處還在於,它同樣是討論編程模式的書籍,甚至可以毫不誇張的說,本書堪稱動態語言的 《設計模式》。

這本書以 Metaprogramming 爲主題,深入討論了基於 Ruby 的各種編程模式,而這些模式,可以通用於各種動態甚至靜態語言。 在閱讀過程中,我不斷的聯想起過去在各種語言中學習到的知識,現在,它們被本書的作者 Paolo Perrotta 用 Ruby 語言, 用他構造的精彩的文字編織起來。

在本書中,我找到了 Python 的參數化 yield、decorator,元類,MixIn, Perl 的 eval,C# 的 using (Python的with),閉包, Smalltalk 的 extend(objective c的category),lambda、block 等等等等。通過這本書,不僅僅瞭解如何在 Ruby 中使用這些技巧,還有如何用 Ruby 實現它們,或如何用 Ruby 的語義來解釋它們。從而,理解這些東西以後,也就可以將它們應用於 Python、Perl、PHP、Objective C,甚至 C++ 和 Java。書中的知識,完全可以視作是動態面向對象領域的《設計模式》, 特別是附錄中總結的各個條款。

通過這本書,我們還可以瞭解到爲何 Ruby 看起來如此與衆不同,它的設計目的,實現方法。我們會瞭解到 Ruby 中大量的內置方法, 其實不僅僅是魔術方法,它們其實是基於一個很小的理論集合建立起來的公理體系。 Ruby 語言的設計,關鍵字只是一部分, 基本對象的設計甚至更爲重要,基於一組精心設計的接口方法和一個作用域理論,就形成了 Ruby 優雅的語義模型。 程序員在編寫 Ruby 代碼(甚至是其它動態語言,甚至 objective c)時使用到的各種方法, 都是基於這個很簡潔的理論內核推導演繹而成。這裏面的魔法非常少,但是完整的描述了動態面向對象的各種設計方法。 甚至可以說,Ruby 是 Samlltalk 族系的 Lisp。讀過這本書,我們可以理解,爲何 Perl 社區的傳奇人物唐鳳會評價" Ruby 就是沒做廣告的 Perl6"。

這本書,我強烈推薦給 Ruby 程序員、愛好者和其他對面向對象知識、程序設計理論有興趣的人。無論你是否使用 Ruby , 只要可以讀懂書中的代碼,就足夠從中受益了。這並不需要很好的基礎。當年我讀《設計模式》的時候,對Smalltalk一無所知, CPP 也不算非常瞭解。現在讀這本 《Ruby 元編程》之前,其實也只讀過 Ruby 和 ROR 官網的 Tutorial, 但是靠對 Python 和 Perl 的瞭解,同樣可以順利的閱讀本書,相反還從中學習到了大量的 Ruby 語言知識。

深入 Ruby 編程的化境

本書可以當之無愧的稱爲 Ruby 編程的高級技術教程。雖然全書討論的話題緊緊圍繞"元編程"這一主題, 但是涉及了軟件開發的很多問題。分析問題、解決問題、構造測試的各種步驟,對 Ruby 的運用出神入化。 而且基於故事背景講述,語言生動自然,言之有物,絕不會讓人感到乏味,可以說是針對 Ruby 語言的優秀教程。

精彩回顧

在閱讀本書時,有很多片段令人讚歎。我這裏舉幾個印象比較深刻的:

一切皆對象

曾經有個說法,Python 是面向對象的,Ruby 是面向類型的。本書回答了這個問題,Ruby 確實是完全面向對象的, 而且,它在語義上更爲純粹。Ruby 可以用自身的代碼完整的解釋自己的對象模型,包括核心的基礎類和方法。設計 Ruby 語言,包含了設計它核心的對象和對象方法,這在現代的編程語言中是常見的,但是 Ruby 做的特別徹底和優美, Ruby 很好的繼承和發揚了 Smalltalk 的思想,它對面向對象模型的抽象,就像 Lisp 對程序語言的抽象一樣徹底。

Ruby 的對象模型中,對象、類、本體類(Eigenclass)、作用域、消息、self 等重要概念, 和它們的實用意義,都在本書得到了闡述。

作用域的封裝、訪問、互操作

Ruby 有嚴格完整的作用域限制,在本書中有詳細討論,包括不同作用域之間如何互相隔離,又如何在它們之間傳遞信息。 基於作用域,衍生出了 block ,然後是 lambda 和 proc 的使用、原理、區別。

扁平化作用域、潔淨室、閉包等概念,都在實例中講解清楚,Python 程序員可以借鑑這些知識,深入瞭解 yield 和 nolocal 等知識。

書中還討論了類和模塊的區分。

eval 族系

Ruby 有 eval、instance_eval、class_eval 三個不同的eval函數,它們可以接收字符串或代碼塊, 這比 Python 的 eval 要複雜,但是從理論高度理解,就會發現它們相當的嚴謹和簡潔。 這些方法可以幫助我們構造或訪問特定的作用域,或許會讓 Python 程序員想到 yield 的使用。而 Objective C 也已經加入了很多 block 支持。

Perl 的 eval 經常用於異常處理,本書也討論了 Ruby 的一些異常處理技巧。

提到異常處理,文中專門有一個例子模擬了 C# 的 using 關鍵字,這個關鍵字曾經是我面試 C# 程序員時的考題內容。將這個例子稍加擴展,就可以編寫一個類似 Python 2.7 中多參數 with 的實現。

Eigenclass ,面向對象和類型約束

Ruby 引入了 Eigenclass 概念,它優雅的解決了 duck typing 和對象類型之間的矛盾。 instance_eval , class_eval 和 method_missing 等方法,組成了 Ruby 的動太對象操作集。它們使得 Ruby 在類型約束和動態對象之間遊走自如。 相對於 Python 的 duck typing 風格和 Java 的靜態約束,Ruby 更爲平衡, 允許用戶自己選擇約束與自由的平衡點。相對於在 Java 中使用反射或 Python 中使用約束,Ruby 無論傾向哪一種風格,都不會付出太高昂的編程代價。

學習這部分知識時需要注意的時,Ruby 中的單件(Singleton)不代表通常意義的單例模式, 而是通常說的動態對象,即 duck typing。

MixIn 和其它類型擴展方法

類型混入(MixIn)在 Python 中也是重要的元編程技巧,著名的 Python 編輯器 Ulipad 就大量使用了這種技術。Ruby 對 Mixin 的支持更漂亮,也更靈活,這個技術在書中反覆使用。

Ruby 同樣繼承了 Smalltalk 的 extend(這裏指 Smalltalk 的 extend , Ruby 的 extend 則表示了不同的含義) 方法,這個技巧在本書一開始就有介紹,並且反覆使用。

Objective C 雖然沒有 Ruby 這樣豐富完整的面向對象語義(相對來說,objective c擁有 C 級別的運行效率和底層訪問能力),但是學習 Ruby 的各種類型擴展技術, 可以幫助我們更好的理解和運用 Objective C 中的 category 等技術。

符號與文本

對文本直接 Eval 當然非常靈活,特別是 Ruby 具有 Perl 和 PHP 的變量內插能力, 但是它也有其缺陷,書中詳細討論了這個問題,介紹了一些應對方法。LISP 程序員相信會注意到 Ruby 有在符號和文本之間進行轉換的能力,這就像 LISP 宏和 Python 自省的結合,好吧,Ruby 也有自省,而且更強大。

Objective C 程序員也可以從中增強對 SEL 和 @selector 等概念的理解。

本書中多次使用的類宏,不同於 LISP 的宏,雖然它也是一種生成技術。這一點 LISP 程序員不要簡單代入。在我看來, LISP 宏與 Ruby 類宏的差異,比它與 CPP Template 的差異更大。

屬性、訪問器與幽靈方法

屬性封裝、訪問器等概念在多種語言中都有體現,本書用 Ruby 的各種內置方法和設計方法, 向我們展示了這些概念在語義上到底是如何被設計和理解的。學到這些知識,對 Python、 和 C# 等領域的程序員,理解日常工具中出現的 property 技術,也有很大幫助。

深入閱讀 method_missing 相關的知識,不僅可以瞭解 Ruby 的動態屬性和方法技術, 還可以幫助我們深入瞭解爲何 Smalltalk 觀點中的對象是消息驅動, 而非表面看來簡單的函數執行。Objective C程序員也可以藉此更好的理解 KVO、KVA 等技術。

請深入閱讀

閱讀本書對於編程語言控、設計方法控,是莫大的享受,即使我這個從來沒有實用過 Ruby 的門外漢,也感到了不能自拔的愉悅。我這裏只是憑印象選擇了一些讓我激動的點來介紹。 書中的精彩,只有自己去閱讀才能體驗。

除了方法講解和生動的故事實例,本書還穿插介紹了很多 Ruby 的第三方資源, 包括著名的 ROR。

我向我的同行強烈推薦這本書,閱讀它,各種不同技術的使用者都會不虛此行。

說說反話

儘管讀完這本書以後,或許你也像我一樣對 Ruby 產生了濃厚的興趣,但是我要提醒本文的讀者, 不要誤認爲 Ruby 是解決一切問題的完美方案。Freedom 不是無代價的, Smart 同樣不是無代價的。 Ruby 強大、優美、完備的語言設計,需要付出很高的性能代價。

相對來說,儘管我不斷的在文中提及 Python 比之 Ruby 的模型,如何簡陋,但 Python 的確有性能優勢,它剪裁了 Smalltalk 理論中的一部分,通過建立在 C 語言環境上的字典模型實現出來。這使得它的動態模型非常容易理解,並非像 Ruby 這樣充滿了魔幻和神祕感。而且 Python 代碼很容易獲得更高的性能。儘管 Ruby 的近幾個版本在性能方面有了長足的進步,但是 Python 仍然遠遠的將其拋在後面。前有 Bigworld、 EVE、stackless Python,後有 Torando 這樣的高性能應用,充分證明了 Python 作爲架構級技術,在性能方面有足夠優秀的表現。恰到好處的語言設計, 也使得它在開發效率上,仍處於最優秀的幾種語言之列。

對於喜歡腦力風暴的 GEEK 程序員,即使有了 Ruby ,也不等於其它語言就不值得學習和使用。性能、 表現形式,或特定領域的突出表現,都會促使我們做出選擇。例如 Perl 的鋒利,LISP 的美感, LUA 的輕捷。但是無論你是哪一種語言的使用者,只要你對面向對象、動態模型或編程有興趣, 我都誠摯的向你推薦這本 《Ruby 元編程》。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章