這是我現在拿來寫 Blog 的 Editor。原先是使用付費軟體 iA Writer,後來九月底在 twitter 上看到朋友推薦使用 Mou,毫不猶豫就放棄了原來的 solution,現在越寫越上手。
如果你是 Markdown 愛好者,一定會愛死它的。
不多說,直接來一張截圖。
CJK 也是沒問題的
知道為何我狂更新 blog 的原因吧....XD
(目前支援 Mac OSX 10.7+,作者有說其實在 10.6 上也可以執行,但它不會修理任何 10.6 上出現的 bug )
d
d
d
d
d
d
d
d
d
d
dd
原本是承諾讀者要整理一篇我常用的工具集,後來想想其實應該要改成來寫一篇:「十個 Ruby Web Developer 應該熟悉的工具」。
1. Git
Git 是進入 Ruby 這個生態圈首先最應該學會的工具。幾乎所有以 Ruby 開發出來的套件都放在 Github 上。也就是不管你要下載或修改協作都需要透過 Git。
2. RVM
Ruby 有很多種 implementation,比較多人在使用的有
- 標準的 MRI Ruby 1.8.7
- 標準的 MRI Ruby 1.9.2
- REE ( Ruby Enterprise Edition)
- JRuby 等等
其實你用哪一種版本開發都無所謂,不過目前有一些 project 只能在 Ruby 1.9.2 上執行。切換 Ruby 環境跑實驗 project 在之前的時代是一件很痛苦的事。
所以有人發明了 RVM,讓開發者可以無痛的可以切換各種 Ruby 環境,甚至透過 RVM 製造出獨立的 Gemset 環境,無負擔的盡情實驗新工具。
3. Mac
不可否認的開發 Ruby 程式,Mac 是第一首選環境。
最初的原因是撰寫 Ruby / Rails 的利器: TextMate ,是 Mac 上的軟體。而後來使用 Mac 開發 Ruby 程式的開發者越來越多,更加深這種情況,
造成一些實戰 best practices 以及友善的開發工具,幾乎都以 Mac 為優先或唯一平台發佈,如:Pow 與 Homebrew。
4. Homebrew
原先在 Mac 上,套件管理幾乎是 Macports 與 Fink 的天下。但這兩者因為 dependency 處理不佳,加上需要 sudo 執行。某些時候會造成套件管理上的災難。
在 OSX 10.6 之後的時代,就逐漸被後起之秀 Homebrew 取代。
Homebrew 有兩大極優秀之點:
- by user,不需 sudo 就可以安裝套件。不會把檔案權限搞得一團髒。
- 更新迅速以及乾淨。Homebrew 是 git-based 的 fomula sets,透過預設的 fomula 安裝程式。
安裝時如果發現有錯誤,可以自行修改,並透過 Github 的功能發 pull request 要求管理者 patch。用 Homebrew 建置出來的 Rails 開發環境通常極為乾淨且無惱人的套件 bug。
( Rails developer 最常會撞雷的兩大套件:MySQL 與 ImageMagick 在 brew 上裝,幾乎沒什麼問題...)[註1]
5. Pow
這是由 37signals 所開發出來的網頁伺服器,可以跑任何 Rack Based 的網頁程式。特點是,你可以把某個開發中的 project,如:wiki,symlink 到自己的家目錄底下的 .pow/ 資料夾。
再打開瀏覽器上的 http://wiki.dev/,就可以把 projects 掛起來了。
(原理是攔截對 port 80 上的 request 導回 Pow)
在從前,如果你要掛上 projects,通常得自己改 local 的 apache conf 和 /etc/hosts 加上設定。掛起、移除、重開都非常麻煩。
而 Pow 的誕生,讓常常追許多新玩意的開發者,實驗的成本變得極度低廉。
6. Rack
Rack 是一個 Ruby 套件,也同時是 Ruby 界的網頁程式標準 interface。背後的想法與原理可以參考我以前寫的一篇舊文 Rack 與 Rack middleware。
現在只要看以 Ruby 開發的網站程式,幾乎都支援 Rack。不會再有以前哪一套框架,推薦獨家使用哪一套 web server 跑的亂象。
而因為有了 Pow,掛起 Rack-based 的網站實驗程式成本也很低廉。
同時因為採用 Rack 架構開發的緣故,開發者可以透過 Rack middleware 外掛實作一些框架或程式沒有的功能。
比如說:
- rack-now-www 硬是幹掉網址的 www
- rack-rewrite 在不支援 .htaccess 的環境下,直接使用 rack 硬 rewrite routing
也很自然而然的會知道:
- 想惡搞,改 config.ru
- 想重開,touch tmp/restart.txt
這些潛規則。
7. Bundler
Bundler 原先是 Rails3 架構師 Yehuda Katz 開發出來解決 Rails 中 package dependency 的工具( 在開發 Merb 這個 framework 時,Katz 就開始嘗試實作了)。
package dependency 一直是相當麻煩的問題。解不開,就無法將程式 boot 起來。
原先大家也只有拿 Bundler 搭配 Rails 使用。
而後來 Bundler 也逐漸變成一般 Ruby 程式中預設的套件 dependency 管理程式。
Bundler 中的 Gemfile 設計,不只能讓開發者能夠輕易的解決套件相依問題,並且可以直接引入「開發中」套件,解決 3rd gem 版本更新過慢,卡住自己開發進度的問題。
8. Guard
在開發網頁程式時,開發者很常重複這樣的動作:寫一寫 -> run test -> refresh web browser -> 繼續修改 -> run test -> refresh browser
這些都是很機械式的行為,非常煩人。
有沒有辦法只要「檔案變更,就自動作事」呢?
Guard 就是這樣的一套工具。
有趣的是,Guard 剛推出時,其實也只單純是一套監視檔案工具變動的工具,你可以透過寫 Guardfile,去自由監視需要監視的資料夾,再 do something。而因為 Guard 架構算設計的不錯,後來許多開發者更基於 Guard
做出更多其他的 rubygems。
guard-livereload 就是一個例子。
9. LiveReload
修改網頁 => refresh browser 是剛剛所提到的煩人事之一。
LiveReload 提供了監視檔案變動,並通知 browser reload 的功能。
開發者如果螢幕夠大的話,可以同時開著文字編輯器與 browser,修改的任何變動馬上即時顯示在 browser 上。
值得一提的是,LiveReload 在 10.7 以後是 broken 的。因此後來有人利用 guard 實作出了 guard-livereload 作為替代品。
以前寫過舊文一篇:LiveReload:你的套版好幫手!
10. Sass / SCSS / Compass
自從 Rails 3.1 引入 SCSS 作為 Asset Pipeline 當中的選項之後,這套本來沒多少開發者知道的 CSS framework 就開始瘋狂走紅。
SCSS 的原理是透過寫編寫「巢狀」的 style,取代原本需要寫 CSS 時需要一直複製 DOM 結構名稱的動作。並且支援變數、數學、繼承、mixin 等功能...
如:
可以生成
而 Comass 是基於 SCSS 的 Framework。提供了更進一步的許多暴力 feature。
有些人可能會搞不清楚 SASS / SCSS / Compass 的關係。如果你有興趣的話,可以參考我在 Upgrade2Rails31 這個 project 中寫的兩篇文章:Sass/SCSS 以及 Compass。
這兩天因為本來嘗試要將 Wordpress 轉成 Octopress 的緣故。寫了不少 script。而壓出來的 MySQL 備份檔大概也有 11 M。原本以為是 spam 佔了很多份量。沒想到去掉 comment,還是足足有 10 多 M...
才發現自己好像還真的寫了不少字。
好奇用 wc 跑自己的文章目錄夾,得出一些有趣的數字:
文章:840 篇
字數:2312404 字。
歷時 1902 days
平均 2.23 天寫一篇文章
平均每篇文章長 2752 字。
這個數字跑出來我自己也嚇了一跳,因為實在是遠超乎自己的想像。
這件事也在某種程度上提醒和鼓勵了自己:持續做一件微小的事,時日一久也可以匯集巨大成果。
OctoPress 是一套Blog Framework。也是我這個 blog 正在用的系統。
用了這麼久(5 年)的 Wordpress,突然放棄,你一定會好奇背後真正轉換的原因。
Wordpress 是一個很方便的 Blog 系統。
但很可惜的,一直以來它一直是一個給文字書寫者用的部落格系統。
怎麼說呢?若你是一個專門談論技術的 blogger,用 Wordpress 寫一篇技術文帶給你的感覺通常是無比…麻煩。
樣樣麻煩
貼圖很麻煩。(我們有潔癖,不喜歡直接傳圖直接上 Wordpres,通常會傳上 flickr 再 embd script)
程式排版很麻煩。如果不裝一些 plugin,幾乎無法貼程式語法。但是通常 plugin 也需要你寫特殊語法排這些程式碼。生出來的東西也很差強人意。
Hosting 很麻煩。安裝 Wordpress 需要租一個 LAMP 的 stack 去停泊,沒事你還要害怕機器炸掉,沒有備份。上班摸一整天機器了,下班根本不想再弄…
版本控制 很麻煩。以前的 blog 系統沒有自動備份,視窗一炸掉,文章 99% 就是不見了。而雖然現在 Wordpress 還有一些其他 BSP 有自動儲存功能。但你我心知肚明那只是醫手殘。你只有辦法撈上最近幾個版本,去把文章存回來。若要看自己上次 因為什麼理由,修訂了這篇文章的草稿 根本辦不到。
改 theme 很麻煩。如果需要自己訂一些 tips 等方塊,要自己另寫 CSS,但是改 wp-theme 再生效實在是很麻煩的一件事。而且可不可以讓我直接寫 SCSS就好?
寫作 很麻煩。雖然這一點寫出來算有點雞蛋挑骨頭。但是使用 Markdown 書寫文章,實在遠比用黏膩膩的 HTML 語法快多了。
樣樣都煩啊!想到就懶!!
Developer Blogger 的需求
其實我們的需求也不多。若是可以:
- 輕鬆的撰寫 Markdown
- 輕鬆的貼圖
- 輕鬆的貼程式碼
- 改 CSS 超容易
- 不用煩惱佈署問題
- 檢視草稿變化,甚至是站台更動變化。
這樣就很開心了!
Octopress
而 Octopress 就是這樣一套會讓人開心的 Blog Framework。
- 輕鬆佈署
Octopress 背後是一套叫 Jekyll 的靜態網站產生引擎,可以輕鬆產生 static-file based 的網站,佈署出去。
你可以選擇放到自己的機器,Heroku,甚至是 Github Page 上。
佈署簡單到只要一個指令 rake deploy 就出去了!
- 輕鬆撰寫文章
Octopress 支援 Markdown,直接解決了寫作和貼圖的問題。
而程式碼的排版更不用煩惱,可以直接使用 Markdown 原先的 block 貼程式碼,只要註記語言種類,就會自動排版上色。(格式也與 Markdown 語法完全相容)
更令人讚嘆的是可以內嵌 Gist。這不知道有多酷啊…
- 使用 Git 版本控制
Octopress 本身不需使用任何 database,架構本身靠的是文字檔案以及版本控制系統。可以透過使用 Git 觀看站體與文章的修改變化。
而我現在寫文章還常使用進階的招數:開 Git branch 把 TODO 扔進 TODO branch,這樣就算我還有文章沒有寫好,或者是日後需要補充,都不需要另外管理以及害怕被人看見。
- 更改網站配置更方便
Octopress 雖然基於 Jekyll,但用起來比 Jekyll 更方便,不少功能都是內建模組化,比如:社群功能(Twitter / Google plus)、留言功能(DISQUS)、統計功能(Google Analytics),這些都簡單到只要改 _config.yml 就可以改一改,馬上就可以有一個 Blog 上線了。
- 對 Ruby Developer very very very friendly
Octopress 是 Ruby-based 的。自然許多 feature 是取用 Ruby Ecosystem 熱門架構與套件打造的。
熟悉 Ruby 的開發者,可以透過:
- Rack
- Rake
- SCSS
- Guard
- LiveReload
- Heroku
就玩出更多花樣。
寫出 Octopress plugin 更不是什麼難事。
小結
Wordpress 爛歸爛,但如果不挑的話,還算是可以用。一直以來,我都認為自己寫文章的速度,若不被平台和工具綁住的話,其實寫作速度還可以更快,寫作興致還可以更高昂。
想歸想,但實際上找不出解法去解決問題。
這件事,一直到了我漸漸接觸到了 Markdown 、 iAWriter / Mou 、 Jekyll / Octopress,慢慢被改變了。
後來實際用了 Octopress 認真架了一個關於 「Upgred2Rails31」 的教學網站,放置升級到 Rails 3.1 的教學筆記。
寫著寫著,更加深了我這樣的信念。我寫作的速度,文章的長度,還有文章的有趣度,無一不被提高了!
加上我本身的職業就是 Ruby Developer,要 Hack 這個系統根本不是什麼難事。這個職業反而有加分作用。
最後,就是你看到的:我終於鼓起勇氣把用了五年的 Wordpress 扔掉了 XD
Wordpress 用到今年,也第五年了。發現越來越不敷我的需求。
決定轉戰 Octopress。
原本是打算 host 在 Github 上,這樣比較炫(?)
後來考慮到要支援舊 blog 上的文章。所以最後還是放在 Heroku 上,用 rack-rewrite 對所有舊文章轉址。
舊文章會通通放在 http://wp.xdite.net。舊站的文章我就不繼續再更新了。feed 應該不受影響,本來就放在 feedburner 上。
至於迴響也會轉放在 disqus 上。
大概就這樣...
本來曾經考慮要連內容都轉過來,連中文亂碼都搞定了,不過排版要重弄就有點懶了。
再來是 compile 的速度,我在舊站寫了大概約 850 篇文章。轉過來每 compile 一次對我來說就是一次折磨。
算了 :Q
因為最近還蠻常私下被問 Rails BDD / TDD 的一些議題,但是回答之中,卻發現對方對 BDD / TDD 的想像有些奇怪,因為對不同人重複講了好幾遍,乾脆整理一下我對這件事情的看法好了。
我個人的看法是認為在大多數的情形下,你需要對你的「軟件」寫 "Test",而且是要先寫 "Test" 再行撰寫程式,也就是 Test-Driven Development。因為程式碼會逐漸龐雜,沒有人可以 write code without bug,也不可能每次都有辦法用手測出來,加上有時候寫錯程式時的損失不是事後修理就有辦法彌補的,所以我們必須要寫 Test Case,及早抓出問題。
這是所謂寫測試的重要性。
然而,我要強調,這卻不是程式設計師「可以」不合時宜的盲目在「任何類型」的專案強行導入 BDD / TDD 的藉口。
而上個月看到 The Rails3 Way 的作者 Obie Fernandez 在 Rails Conf 2011 的 lightning talk Why BDD is Poison For Your Early Stage Startup 後寫的這篇文章 The Dark Side Beckons? 更強化了我這樣的看法。
這世界上沒有所謂治百病的蛇油,不是用了 XX 就能 XX 。任何 Solution 都有 Pros / Cons。
1)「 寫測試 + 寫程式」 所花的時間,大概是純寫程式的 1.5 -2 倍時間。
2) 「會寫 Test」、「正確的測到該測的部份」、「寫出好的測試」,都需要學習時間以及功力。
很多程式設計師因為厭倦了維護在之前的專案後期的維護因為修改程式碼,而一再發生的問題(無論是小問題,大問題),而決定在下個專案,無論專案類型都要導入 TDD / BDD,在我眼中認為這是相當不正確的事情。
我的理由是如此的:
1) 每個專案類型不盡相同,有的是要求高正確性且牽扯到金流問題且開發時間充裕。有的純粹只是 event,用過極丟。有的是幫人外包,只要求規格正確,開發時間不寬裕。有些則是混合型。有些部分的程式碼則是相當難以寫測試(如 View),C/P 值極低。應該考慮每個專案的類型甚至是 component 去決定哪部分該嚴厲的規定寫測試,而哪些部分可有可無。
2) Startup 前期應不應該導入 TDD/BDD ? 我認為不應該。為什麼,很多人都認為 TDD / BDD 是為了確保「程式的正確性」,所以無論如何我們都應該執行。卻忽略了 Startup 的成功要素是「快速驗證你的 Idea 的正確性」、「快速應付市場變化調整的速度」、「在市場廝殺中節省成本存活下來」。
3) 寫測試只是為了要能自動驗證「程式的正確性」、降低「程式出錯的機率」,但團隊合作開發程式最重要的是團隊中的「溝通」,大家對 function 和架構要有一定程度以上的理解,共同撰寫程式要有一定程度以上的 convention。變更任何重大架構(如 core function, db schema, 底層設計前)都要提醒大家。
如果每個人都只寫自己的,然後想改什麼東西照自己心情,沒有人想舉手之勞通知大家、跟隊友溝通。坦白說,那寫測試有個屁用,可能只是不會爆 production code,development 拉下來還是爛光光,還是要修到死。
完全不溝通、不制定規範,卻期待寫測試能夠解決一切,這樣的想法不是很奇怪嗎?
4) 無論如何,就算寫了再完美的測試,再完美的程式碼。程式還是可能在你完全預期不到的狀況爆掉,所以應該做的是要接受無論如何就是要修 bug 的這件事,然後想辦法把修 bug 的成本儘量壓低,也把因為 bug 會產生的損失也儘量壓低。
不要期待測試是萬靈丹。否則期待越大,失望也大。
這是我對於寫測試的一些看法,歡迎各位指教。