關於完全聽不懂 Ruby 元編程在說什麼的事(零)
元 (meta-) 是什麼?
很難用一個中文的辭彙來概括英文中 meta- 詞綴的含義。如果我們去找這個詞綴詞語的翻譯的話,也很難找到究竟是什麼時候,開始將這一類詞翻譯成「元XX」的。但我們可以看到的是,這一類詞通常都很難翻譯,比如說 physics 物理,metaphysics 形而上學;morphological 形態的 metamorphosis 質變。
對於這個詞,我認為有個非常有趣的英語翻譯,是捷克小說家卡夫卡的著名小說《Die Verwandlung》(變形記)的英語翻譯《The Metamorphosis》。因為德語 Verwandlung 本身更接近於 change, transformation 的意思,而 metamorphosis 更突出了變化的徹底性,更體現了主人公格里高爾變成跳蚤之後個人、家人、社會對他的全面變化。
meta- 這個詞綴更類似於關於 x 的 x 的這麼一種感覺。比如 metaphysics 在討論的是事物原理本身的原理,metamorphosis 討論的是變化導致的根本變化。meta- 這個詞綴源於希臘語前綴 μετ?,意思是 「之後」、「之外」、「之上」、「之間」。中國大陸一般將這個詞綴的詞翻譯成「元」,而台灣地區通常翻譯成「後設」或「超」。
在討論元編程之前,我們不如先討論一下,元概念是如何被用於其它創作性工作的,這樣我們可以更好理解元編程,以及如何將元編程用於編程工作之中。
將元用於文學性創作
塞萬提斯的《堂吉訶德》通常被認為是最早的元小說之一。故事發生在已經沒有騎士的年代,主角堂吉訶德幻想自己是一個騎士。這種在小說作品中創作的形式就可以被認為是元小說。更嚴格的元小說通常是故事中的作家創造另一個故事或故事中的讀者閱讀一本書,比如《蘇菲的世界》。
現代和後現代時期的元小說產生的一大特點是,故事主角對自己是故事的一部分這樣的概念具有意識。這一類作品的特點也很大影響了其它類型作品,包括元電影和元遊戲。
可交互性更是使得這種自我意識覺醒題材的元創作有了更多的創作型。比如著名獨立遊戲《史丹利的寓言》(The Stanley Parable) 就以玩家與旁白之間的聽從與對抗作為手段,試圖討論遊戲本質和玩家自我意識的概念。
將元用於理學性創作
如果說當你將元用於文學性創作時,你是有意識地進行著元創作;當你將元用於理學性/科學性的創作的時候,你通常是無意識的。就好像相聲中的傳統段子《捧逗爭哏》,就可以稱之為元相聲,只不過是沒有人這麼叫而已。
大學數學中有一門有關形式語言的課程叫範疇論。其實就是用抽象的方法來處理數學概念也可以稱之為元數學。在計算機科學中,元概念的應用其實極其普遍,以至於我們其實在日常開發中無數次使用過。
當我們現在有一個 HTTP 伺服器,用戶訪問伺服器通常都會返回一個網頁。但我們有時需要返回的是一個給用戶下載的文件,在這種情況下,瀏覽器需要不同的方式來處理這是個網頁還是文件。最常見的就是我們會通過 HTTP/1.1 的 Headers 中的 Content-Type 來定義瀏覽器應該如何處理收到的數據。而這些 Headers 定義了數據本身,作為一種描述數據的數據,我們就可以稱之為元數據。
當你設計了一門編程語言,你需要為它實現一個編譯器。而編譯器的一開始,你需要做一個語法分析器 (parser)。由於一門編程語言的語法通常非常複雜,手動定義其中的關係有時不那麼方便,於是很多時候我們會有類似於 yacc 之類的編譯器編譯程序 (compiler-compiler) 來生成。通常這樣的程序會允許輸入一個巴科斯範式 (BNF) 作為語法定義,而巴科斯範式本身就可以被認為是一種元編程,你在通過編程實現編程。
Ruby 元編程
我們通常把 Ruby 元編程單獨拿出來說是因為 Ruby 可以通過編程修改 Ruby 語言自己。事實上,有這種能力的不止 Ruby 本身。且不論 Lisp 的各類方言,當年 C++ 模板元編程技術就夠大家喝一大壺。如果說 Ruby 元編程被 Rubyist 經常單獨出來說的原因是,我們可以通過元編程,不僅僅是給語言「增加」能力,或者是在 Ruby 上開發一個「DSL」,更多的是依靠 Ruby 本身豐富的語法糖設計,帶來更好的編程範式和靈活性。
但 Ruby 元編程並非是一個有益而無害的東西,錯誤地使用元編程會給代碼可讀性和程序性能帶來災難性的後果。這一系列的文章將通過介紹 Ruby 元編程來達成以下目的:
介紹 Ruby 元編程方法
介紹 Ruby 元編程陷阱
介紹 Ruby 元編程原理
相關方法在 YARV 中實現的變化
認為 Ruby 不再是魔法
能找到使用元編程技巧的正確場合
比較 Ruby 和其他語言的元編程實現
寫這些文章之前我反覆讀了《Ruby 元編程》和《Ruby 原理剖析》這兩本書,結合我自己 Ruby 開發的經驗和實例,在這系列文章中,將會由淺入深地從方法介紹深入到實現細節,更系統地就元編程問題進行討論。
本系列文章採取月更,連載長度約為十二個月,每個月的內容大約 1500-3000 字之間。
推薦閱讀:
※主流程序設計語言的標準庫中,類似於 fopen() 之類的函數的 "w"、"a" 等控制方法有何利弊?
※2015 年的今天,Ruby on Rails 還有哪些獨特的價值?
※Ruby 和 Ruby on Rails 在 2017 年還有前途嗎?
※ruby語言前景如何?
※使用 jeykll 或 octopress 在 GitHub 上架 Blog 的工作原理是怎樣的?