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