IDE是用來創作程序的(這裏之所以不說“寫程序”,是因爲程序不光是寫出來的,還要重構、編譯、調試、管理等);文本編輯器是用來編輯文件的,當然也可以編輯程序源代碼。
我見到網上有爭論說Rubyon Rails不需要IDE,文本編輯器即可,又考慮到文本編輯器與IDE是個曠日持久的話題,所以發表一下我的看法。
本文的文本編輯器主要以(g)Vim7.3爲例,IDE以VisualStudio 2010爲例。制定版本號是避免人家說“VS97或2002不是這樣!”。VS我用了五六年,Vim用了兩年。
關於創作程序
我傾向於認爲創作程序是一項藝術,而不是體力活;我常常自稱自己爲程序構架師,而不是打字員。
創作程序要打字(寫代碼)、編譯、調試、重構(如重命名一個方法內的變量,將方法從子類提升到父類,修改一個接口,以至於繼承此接口的20個類都要發生變化等等)、管理(用文件夾或其他結構組織源代碼等)。顯然,IDE之所以爲IDE,就是因爲I——Integrated(集成)。集成開發環境嘛,以上五種操作一般都包含進了。文本編輯器只支持打字一項。
但是,有些文本編輯器對擴展的強大支持使其生命力旺盛,不僅能編輯普通文件,還能很好地適應多種語言的源代碼。例如,Vim加些擴展就能針對某種語言實現語法高亮、縮進。又加上一些擴展就能實現所謂的自動補全、編譯和調試。這才使得有些人認爲個別文本編輯器可以替代IDE了。
關於自動補全
需要越好的自動補全,越需要IDE。如果你不用自動補全,你可能不需要“智慧型”IDE,如VisualStudio或eclipse。而據我所知自動補全有兩種,一是Vim的Ctrl-p,Ctrl-n之類的,根據上下文中相同單詞來補全。例如,我寫了
Thisis probably my first real blog entry, something of value, thatI probably know more about than most people.
然後寫en,按ctrl+p,就會提示entry。“上下文”的範圍可以是此文檔,或者其他更大的範圍。這種提示不涉及語法。
另一種提示就是VS的IntelliSense,在C#的一個類MyClass中定義了publicvoid Search(string keyword),在另一個文件裏有
intseed=123;
MyClass.
然後寫se,不用按任何鍵,IntelliSense就會提示你Search,而不會提示seed。顯然,我們程序員需要的是IntelliSense。至於“上下文補全”能在多大程度上滿足我們則是另一回事。
有人會說了,Vim加個插件,也能IntelliSense。但是,這勢必涉及語法分析,然而衆所周知,腳本語言的執行速度(如Vim的python、emacs的elisp)沒有C或C++快,所以Vim的IntelliSense不可能比VS快。所以,還不如用IDE。
第二,我認爲創作程序需要自動補全,越智能的越好。有人說,“自動補全使人懶惰,我因此記不住那些常用的方法名了。而改用文本編輯器後,我能下意識地拼出1000個方法名了。”我說過創作程序是一項藝術,我不背方法名,我知道,我只要記住頭兩三個字母,智能補全就能告訴我有哪些方法可用,然後我從中選一個我想要的就可以了。這是填空題與選擇題的差別。我平常沒有在背單詞(背方法名)了,就有更多精力看書,看怎麼設計,就能掌握更上層的知識,寫出更好的程序。寫程序時,我不是在“默寫單詞”,而是專注在程序邏輯上。我不知道“真”是true還是ture,但IntelliSense知道。
關於用法提示
另外,用法提示在程序入門階段和後期也都十分重要。在入門階段,比如我學習怎麼讀取文件,我打File.自動補全提示我一大堆單詞,儘管現代程序基本都偏愛“望文生義式”的命名,但總有些命名不懂其意思或用法。這時,用法提示能告訴我怎麼用它。例如,我要讀文件,file.Re(我不知道讀是reed還是read),自動補全提示我還有Renew方法,我就會好奇看看這個方法幹什麼。用法提示會告訴我。當然了,看文檔也可以學習新方法,最快就是按一下F1之類的快捷鍵,就新打開一個界面,告訴你Renew怎麼用。但用法提示是用中學——寫代碼時不小心看到而學,看文檔是學中學——本來要學A,不小心看到B,順便學一下。用中學比較方便。
這樣的話,如果文本編輯器要支持用法提示,必須要支持語法分析,還要能夠讀文檔。上面說過,語法分析代價大,還不如用IDE。
關於重構
要越厲害的重構,越要用IDE。考慮以下代碼
inta=12;
a=a+12;
a=a*12;
system.out.print(a);
如果我要把a改名爲b,在IDE的語法分析的幫助下,改名就是一個動作,很方便。誠然,在這個例子中,Vim也比較方便,記下第一行和最後一行的行號,寫:1,4s/a/b/gc就行了。(如果有不記行號的方法請告訴我)
但如果一個類中有個私有變量叫name,該類的構造函數(或一個方法)中有個同名參數name(覆蓋了類變量name),我只想修改類變量name(參數name不變),這個修改Vim就不容易做了。
更厲害的重構就不用說了。我有一個接口interfaceIPlayer,有實現類ComputerPlayer和HumanPlayer。我現在在IPlayer新增一個方法GetName(),我在IDE裏可以在IPlayer.GetName()上點擊“在所有繼承類中實現此方法”(通過返回默認值或拋異常來實現此方法),然後就可以編譯通過。這是O(1)複雜度的操作。如果在文本編輯器中,我想不得不變成O(n)的操作,儘管這個n可能是一個粘貼操作而已。
有人會說,重構代表了你一開始設計不完善,沒考慮周到。我用文本編輯器,我寫代碼之前我都打好草稿,想清楚再寫,很少重構。我認爲,這觀點有其道理,但重構是應對變化的手段,而“應對變化是軟件設計的不變真理”。當後來需求變更時,文本編輯器將不得不面臨O(n)的重構。
關於編輯文件
根據上面的討論,越不需要自動補全,越不需要用法提示,越不需要重構,越不像是在創作程序,越可以用文本編輯器。
我不是沒在用Vim,我有把它設置爲默認的文本編輯器,Windows自帶的notepad被我刪了。我用它看各種文件(包括源代碼),確實很方便。注意,我基本是用它來看,偶爾修改文件。因爲它文字處理真的很方便,刪除引號內的文本、連接段落、宏等等。這方面,IDE們就沒這麼強的功能了。我裝了幾個語法高亮插件後,看HTML、Javascript、Java、C#等等都沒壓力了。
所以,我創作程序時結合使用IDE和文本編輯器。VisualStudio可以添加外部工具,我就添加了gVim。我在VS裏編輯、重構、編譯,遇到適合Vim的文本操作時,就點擊菜單上的gVim,就用gVim打開了我正在編輯的源代碼,我做好文字處理,保存,VS提示我源代碼已變,我令VS重新讀取文件,變更顯示出來了,我按F5編譯,新的程序已經躺在硬盤上了。