元 (meta-) 是什么边翁?
很難用一個(gè)中文的詞匯來(lái)概括英文中 meta- 詞綴的含義鸵赖。如果我們?nèi)フ疫@個(gè)詞綴詞語(yǔ)的翻譯的話臀玄,也很難找到究竟是什么時(shí)候,開(kāi)始將這一類詞翻譯成「元XX」的嫁乘。但我們可以看到的是,這一類詞通常都很難翻譯球碉,比如說(shuō) physics 物理蜓斧,metaphysics 形而上學(xué);morphological 形態(tài)的 metamorphosis 質(zhì)變睁冬。
對(duì)于這個(gè)詞挎春,我認(rèn)為有個(gè)非常有趣的英語(yǔ)翻譯,是捷克小說(shuō)家卡夫卡的著名小說(shuō)《Die Verwandlung》(變形記)的英語(yǔ)翻譯《The Metamorphosis》豆拨。因?yàn)榈抡Z(yǔ) Verwandlung 本身更接近于 change, transformation 的意思直奋,而 metamorphosis 更突出了變化的徹底性,更體現(xiàn)了主人公格里高爾變成跳蚤之后個(gè)人施禾、家人脚线、社會(huì)對(duì)他的全面變化。
meta- 這個(gè)詞綴更類似于關(guān)于 x 的 x 的這么一種感覺(jué)弥搞。比如 metaphysics 在討論的是事物原理本身的原理邮绿,metamorphosis 討論的是變化導(dǎo)致的根本變化。meta- 這個(gè)詞綴源于希臘語(yǔ)前綴 μετ?攀例,意思是 “之后”船逮、“之外”、“之上”粤铭、“之間”挖胃。中國(guó)大陸一般將這個(gè)詞綴的詞翻譯成「元」,而臺(tái)灣地區(qū)通常翻譯成「後設(shè)」或「超」梆惯。
在討論元編程之前酱鸭,我們不如先討論一下,元概念是如何被用于其它創(chuàng)作性工作的垛吗,這樣我們可以更好理解元編程凹髓,以及如何將元編程用于編程工作之中。
將元用于文學(xué)性創(chuàng)作
塞萬(wàn)提斯的《堂吉訶德》通常被認(rèn)為是最早的元小說(shuō)之一职烧。故事發(fā)生在已經(jīng)沒(méi)有騎士的年代扁誓,主角堂吉訶德幻想自己是一個(gè)騎士防泵。這種在小說(shuō)作品中創(chuàng)作的形式就可以被認(rèn)為是元小說(shuō)蚀之。更嚴(yán)格的元小說(shuō)通常是故事中的作家創(chuàng)造另一個(gè)故事或故事中的讀者閱讀一本書(shū),比如《蘇菲的世界》捷泞。
現(xiàn)代和后現(xiàn)代時(shí)期的元小說(shuō)產(chǎn)生的一大特點(diǎn)是足删,故事主角對(duì)自己是故事的一部分這樣的概念具有意識(shí)。這一類作品的特點(diǎn)也很大影響了其它類型作品锁右,包括元電影和元游戲失受。
可交互性更是使得這種自我意識(shí)覺(jué)醒題材的元?jiǎng)?chuàng)作有了更多的創(chuàng)作型讶泰。比如著名獨(dú)立游戲《史丹利的寓言》(The Stanley Parable) 就以玩家與旁白之間的聽(tīng)從與對(duì)抗作為手段,試圖討論游戲本質(zhì)和玩家自我意識(shí)的概念拂到。
將元用于理學(xué)性創(chuàng)作
如果說(shuō)當(dāng)你將元用于文學(xué)性創(chuàng)作時(shí)痪署,你是有意識(shí)地進(jìn)行著元?jiǎng)?chuàng)作;當(dāng)你將元用于理學(xué)性/科學(xué)性的創(chuàng)作的時(shí)候兄旬,你通常是無(wú)意識(shí)的狼犯。就好像相聲中的傳統(tǒng)段子《捧逗爭(zhēng)哏》,就可以稱之為元相聲领铐,只不過(guò)是沒(méi)有人這么叫而已悯森。
大學(xué)數(shù)學(xué)中有一門(mén)有關(guān)形式語(yǔ)言的課程叫范疇論。其實(shí)就是用抽象的方法來(lái)處理數(shù)學(xué)概念也可以稱之為元數(shù)學(xué)绪撵。在計(jì)算機(jī)科學(xué)中瓢姻,元概念的應(yīng)用其實(shí)極其普遍,以至于我們其實(shí)在日常開(kāi)發(fā)中無(wú)數(shù)次使用過(guò)音诈。
當(dāng)我們現(xiàn)在有一個(gè) HTTP 服務(wù)器幻碱,用戶訪問(wèn)服務(wù)器通常都會(huì)返回一個(gè)網(wǎng)頁(yè)。但我們有時(shí)需要返回的是一個(gè)給用戶下載的文件细溅,在這種情況下收班,瀏覽器需要不同的方式來(lái)處理這是個(gè)網(wǎng)頁(yè)還是文件。最常見(jiàn)的就是我們會(huì)通過(guò) HTTP/1.1 的 Headers 中的 Content-Type 來(lái)定義瀏覽器應(yīng)該如何處理收到的數(shù)據(jù)谒兄。而這些 Headers 定義了數(shù)據(jù)本身摔桦,作為一種描述數(shù)據(jù)的數(shù)據(jù),我們就可以稱之為元數(shù)據(jù)承疲。
當(dāng)你設(shè)計(jì)了一門(mén)編程語(yǔ)言邻耕,你需要為它實(shí)現(xiàn)一個(gè)編譯器。而編譯器的一開(kāi)始燕鸽,你需要做一個(gè)語(yǔ)法分析器 (parser)兄世。由于一門(mén)編程語(yǔ)言的語(yǔ)法通常非常復(fù)雜,手動(dòng)定義其中的關(guān)系有時(shí)不那么方便啊研,于是很多時(shí)候我們會(huì)有類似于 yacc 之類的編譯器編譯程序 (compiler-compiler) 來(lái)生成御滩。通常這樣的程序會(huì)允許輸入一個(gè)巴科斯范式 (BNF) 作為語(yǔ)法定義,而巴科斯范式本身就可以被認(rèn)為是一種元編程党远,你在通過(guò)編程實(shí)現(xiàn)編程削解。
Ruby 元編程
我們通常把 Ruby 元編程單獨(dú)拿出來(lái)說(shuō)是因?yàn)?Ruby 可以通過(guò)編程修改 Ruby 語(yǔ)言自己。事實(shí)上沟娱,有這種能力的不止 Ruby 本身氛驮。且不論 Lisp 的各類方言,當(dāng)年 C++ 模板元編程技術(shù)就夠大家喝一大壺济似。如果說(shuō) Ruby 元編程被 Rubyist 經(jīng)常單獨(dú)出來(lái)說(shuō)的原因是矫废,我們可以通過(guò)元編程盏缤,不僅僅是給語(yǔ)言「增加」能力,或者是在 Ruby 上開(kāi)發(fā)一個(gè)「DSL」蓖扑,更多的是依靠 Ruby 本身豐富的語(yǔ)法糖設(shè)計(jì)唉铜,帶來(lái)更好的編程范式和靈活性。
但 Ruby 元編程并非是一個(gè)有益而無(wú)害的東西律杠,錯(cuò)誤地使用元編程會(huì)給代碼可讀性和程序性能帶來(lái)災(zāi)難性的后果打毛。這一系列的文章將通過(guò)介紹 Ruby 元編程來(lái)達(dá)成以下目的:
- 介紹 Ruby 元編程方法
- 介紹 Ruby 元編程陷阱
- 介紹 Ruby 元編程原理
- 相關(guān)方法在 YARV 中實(shí)現(xiàn)的變化
- 認(rèn)為 Ruby 不再是魔法
- 能找到使用元編程技巧的正確場(chǎng)合
- 比較 Ruby 和其他語(yǔ)言的元編程實(shí)現(xiàn)
寫(xiě)這些文章之前我反復(fù)讀了《Ruby 元編程》和《Ruby 原理剖析》這兩本書(shū),結(jié)合我自己 Ruby 開(kāi)發(fā)的經(jīng)驗(yàn)和實(shí)例俩功,在這系列文章中幻枉,將會(huì)由淺入深地從方法介紹深入到實(shí)現(xiàn)細(xì)節(jié),更系統(tǒng)地就元編程問(wèn)題進(jìn)行討論诡蜓。
本系列文章采取月更熬甫,連載長(zhǎng)度約為十二個(gè)月,每個(gè)月的內(nèi)容大約 1500-3000 字之間蔓罚。