Nic Lin's Blog

喜歡在地上滾的工程師

Meta programming 的雙面刃體悟

我們都知道,在編程寫代碼的時候,都會秉持一些 Best Practices,例如最常見的 DRY ,每一個開發者都希望自己的代碼能夠簡潔且易維護,這不外乎是一個成為更棒開發者的指標,我們在使用動態語言時,能夠輕易達到 Don’t repeat yourself 這個模式。

而 Meta programming ,能夠讓程式自己寫出動態的代碼,豈不是令人稱羨的實踐,但真的這麼好嗎?我們利用短短的一個定義只要五行的代碼,取代原先三個定義而十五行的代碼,看似讓日後的維護工作更容易。

但我卻遇過前輩曾經對我提出的一個問題,如果新人在開發 feature 的時候找不到這個 method 呼叫的源頭,他有可能會對整個專案做全域搜尋,但他可能沒想過這是由動態產生的程式碼,那個時候,他是不是有可能增加了尋找的困難?

起初我認為這是一個說詞而已,阻止使用 Meta programming 的可笑說詞,明明我可以辦到讓程式碼更簡潔, why can’t do it?

直到後來,我才逐漸明白,這樣的動態產生有時是一種雙面刃,他在某部分讓程式碼「看起來」更簡潔了,但可能對往後的每一次搜尋增加了十秒,程式碼永遠都是「讀」比「寫」還要多次,除非你能做到對一個團隊、或是一個專案,在動態產生已經是習慣的事情,例如 Ruby 世界裡最著名的 find_by , dynamic *_path URL path

莫過於更多的單元測試,最簡單的竟是 grep test,如果你不能夠對一個專案搜出其定義的呼叫函式、類別、模組、變數,那麼在重構這些程式碼的時候,會令你感到相當痛苦,這有可能是前人所實踐的 DRY ,但卻給後人留下更多的麻煩了。

comments powered by Disqus