2011年12月30日

我的 vimrc 配置

我的 vimrc 配置 @ GitHub: https://github.com/tzengyuxio/vimrc

Vim in Terminal (Mac)
我一直在用的 vimrc 配置是在我還在以 WinXP 作為主要工作電腦時所配置的, 有超過一年多沒動過了。現在的主要工作電腦以 Mac OS X 為主,當初寫的配置如今有些不合用,然而這好些個日子以來也都是一直將就著用,懶得動手改。終於今天決定要趁著年底來個大掃除,整理一下 vimrc,順便也把程式碼從原本的自家用 SVN 轉移到 GitHub 上。

2011年12月27日

我的 Eclipse 初始設定調教


* 12/30 更新:追加了行號、跳格字元等相關項目

這篇文章是〈Eclipse 安裝筆記〉系列之一,算是個人的安裝過程紀錄。以下是安裝時的環境參考:

作業系統:Mac OS X 10.7.2
程式版本:Eclipse Indigo 3.7.1,IDE for Java Developers

雖說初始設定調教,不過其實要改的地方也不多。現在對於工具的想法我是抱持著盡量不要改太多,以免花太多時間在調整工具上。

以前在不同的軟體間,可能還會改些快速鍵,希望跨不同的軟體時有一致的快速鍵操作,現在都直接讓自己適應。畢竟最常用的快速鍵:剪下、複製、貼上、存檔,所佔用的使用比率高達八成,而這些操作的快速鍵幾乎各軟體平台適用,這就夠了。剩下的查查 cheat sheet 吧,反正真的常用的一定會讓身體記起來的。

所以要做的設定調整很簡單,就是配色編碼行號跳格字元。就這樣。

2011年12月26日

在 Eclipse 開發 Python


這篇文章是〈Eclipse 安裝筆記〉系列之一,算是個人的安裝過程紀錄。以下是安裝時的環境參考:

作業系統:Mac OS X 10.7.2
程式版本:Eclipse Indigo 3.7.1,IDE for Java Developers

步驟流程如下

1. 準備 Python 的編譯環境

同樣的,這步驟在 Mac 上可以略過。在 Windows 上要做的也很簡單,就上 Python 官網抓個 Python Binary 來安裝就好了。相對於 C++ 的準備工作來得簡單些。

2. 安裝 PyDev

在 Eclipse Indigo 之後,套件的安裝變得簡單許多,只要透過滑鼠就可以搞定。首先,先上 Eclipse Marketplace, 一個類似 firefox Extensions 或 Android Market 的地方。搜尋「pydev」,找到後點進去套件頁面,在套件 Logo 下可以看到一個「Install」按鈕,只要將該按鈕拖曳到 Eclipse 視窗中,就可以開始安裝了。

拖曳圖中紫色說明區塊所指向的按鈕就能直接安裝

3. 開始寫 Python

安裝完後重開 Eclipse,如果在選單「File」→「New」→「Project」的對話視窗有看到如下圖的 PyDev 選項資料夾,就表示安裝成功了,可以開始寫 Python 的程式。


不過,等等,要讓齒輪動起來,還少了點東西。CDT 可以自動找到 C++ Compiler 的所在,可是 PyDev 不行,我們得手動指定 Python 直譯器的路徑。

從選單列開啟 Eclipse 的「偏好設定」,切到 PyDev 如下的頁面,點選上半部視窗的「New...」按鈕,輸入路徑「/usr/bin/python」,至於名字可以任意輸入,我習慣加上個版本號。完成之後,PyDev 會自動抓取 PYTHONPATH,也就是下圖中下半部份的視窗。好在這部份不用傷神輸入。


在 Eclipse 開發 C/C++

這篇文章是〈Eclipse 安裝筆記〉系列之一,算是個人的安裝過程紀錄。以下是安裝時的環境參考:

作業系統:Mac OS X 10.7.2
程式版本:Eclipse Indigo 3.7.1,IDE for Java Developers

步驟流程如下

1. 準備 C/C++ 的編譯環境

這步驟在 Mac 上可以略過。在 Windows 上的話則要安裝 MinGW, 關於 MinGW 的安裝可以參考這篇文章


2. 將 CDT (C/C++ Development Tooling) 加入 Software Sites 列表

由於 CDT 是由 Eclipse 官方提供的,因此在預設的「Available Software Sites」列表中可以找到。開啟 Eclipse 的「偏好設定」,並切到「Available Software Sites」頁面,可以看到如下畫面。


如果看到的畫面沒有像上圖那麼多的空白選項,那麼應該是剛安裝好 Eclipse, 還在從 Server 上抓取清單。放著 Eclipse 幾分鐘不動,它會自動於背景抓取選項清單,再打開「Available Software Sites」就可以看到如上畫面了。

接著在「type filter text」的欄位中輸入「cdt」,可以過濾出 CDT 的軟體網址,在前面的格子中打個勾,按「OK」鈕關閉視窗,就完成了這一步驟。


3. 安裝 CDT

完成上一個步驟後,點選單列的「Help」→「Install New Software」開啟 Install 對話視窗。這時候可以在「Work with:」的下拉選單中找到剛剛加入的 CDT Site,如下圖。選取之後會出現安裝內容,我只勾選了「CDT Main Features」,按視窗右下角的「Finish」按鈕,接著就是照著畫面的提示操作了。


安裝完後會要求重新啟動 Eclipse,就給它重開吧!


4. 開始寫 C++

重開後在選單「File」→「New」→「Project」的對話視窗如果有看到如下的 C++ 專案選項,就表示安裝完成,可以開始寫 C/C++ 囉~


等等,這個世界沒有那麼美好。當你建了一個 C++ 專案之後,一編譯下去你會看到 Eclipse 跳出一個 Unable To Launch 的錯誤訊息。


會出現這個錯誤,主要是因為 Eclipse 編譯完要輸出可執行檔,可是卻沒有對應的資料夾可以輸出,輸出失敗,因此會找不到執行檔來 Launch。解決的方式是在左側的 Project Explorer 對專案按右鍵叫出選單,選擇「Build Configurations」→「Build All」,這個動作可以讓 Eclipse 生成對應的輸出資料夾,這樣下次直接 Run 時便可正確產生編譯好的執行檔了。

Eclipse 安裝筆記 - 前言與目錄

用了 Eclipse 也好一陣子了,不過每次需要重新安裝 Eclipse 的時候,或多或少總還是會遇到一些問題。雖然說現在網路很方便,google 一下都可以找到這些問題的解決方式,但為了這些問題免不了又是花上一些時間在搜尋與嘗試上,許多甚至還是以前遇過又重新碰到的問題。因此,不如乾脆自己寫點筆記,既加深印象,就算下次忘了,至少也不用再到茫茫網海中搜尋解決方案。

2011年10月18日

輕量級標記語言 - AsciiDoc, Markdown, reStructuredText

因為最近使用 GitHub 的關係,注意到了 Markdown 這個輕量級標記語言 (Lightweight markup language),跟著查了一下資料才發現原來輕量級標記語言的選項百百款,其中比較常見的有 Markdown, reStructuredText 以及 textile,這三種語法也同時被 BitBucket 和 GitHub 所支援。

稍微看過三者的語法比較後,覺得 textile 的語法太過接近 HTML, 使得文字檔本身無法呈現容易理解的架構。而除了前述三者之外,也另外注意到 AsciiDoc 這一款輕量級標記語言,GitHub 有支援 AsciiDoc。下面就是我對 Markdown, reStructuredText 與 AsciiDoc 的一些比較筆記:

Markdown
使用最為廣泛也最簡單的輕量級標記語言。除了前面提到的 GitHub 與 BitBucket 之外,StackOverflow 的語法基本上也是 Markdown 的強化版,另外 Tumblr 與 Posterous 這兩個輕量級的 blog 也都支援 Markdown 語法。

然而正如前面所提到的,StackOverflow 用的是修改過的 Markdown, 實際上 GitHub 用的也是 Markdown 的修改版本。Markdown 簡單卻又略顯不足,使得許多網站的應用必須增添額外的修改。另外,缺乏表格功能的支援是最大的遺憾。

reStructuredText
以 Python 寫成,主要也使用於 Python 社群中;Python 的文件產生器 Sphinx 就是以 reStructuredText 為基礎。是三者之中功能最為完整的一套,事實上,即便要說是所有輕量級標記語言中功能最為完整的一套也不為過,要拿來寫論文也不成問題。腳注 (footnote) 功能讓人眼睛一亮。不過真的是太複雜了,快要脫離「輕量級」的範圍了。

AsciiDoc
跟 reStructuredText 同樣也是 Python 寫成,不過語法上比較接近 Markdown 的簡單,但也提供了表格的功能。會讓我注意到這一套,最主要原因是因為開源遊戲韋諾之戰 (The Battle for Wesnoth) 的 Manual 就是以 AsciiDoc 所寫成。

線上工具

BitBucket 的 README 支援列表,主要就是以 reStructuredText, Markdown, Textile 這三種為主,README 和 README.txt 這兩個檔名預設為 Plain Text, 不過如果該專案所使用的語言為 Python 的話,上述兩個檔案則會以 reStructuredText 的格式去轉為網頁。

GitHub 支援的格式 比較多種,其中 Markdown 應該是最優先的,從許多專案的 README 都是以 .md 作為檔名後綴不難看出。有趣的是 GitHub 是以 Ruby 開發,然而在 Ruby 社群中比較活躍的輕量標記語言其實是 textile。(順帶一提,BitBucket 是以 Python 開發,Mercurial 也是以 Python 開發的)

10.21 補充:根據 AcsiiDoc 官網上記載,Git User's Manual 也是以 AsciiDoc 所製作。
2011年8月9日

在網頁中嵌入 Facebook 與 twitter 社交按鈕

Facebook 常見的社交按鈕有兩種:Facebook ShareFacebook Like,不過前者已經不在 Facebook 官方提供的 Plugin 列表中,連到舊的 Facebook Share 說明頁面會自動導向 Facebook Like 的說明頁面,看起來 Facebook 似乎有意以 Like 取代 Share 的地位。雖然如此,兩種功能還是有其不同的定位,目前也都能夠共存並用。關於兩者差異的說明,可以參考這篇文章(英文)。下面則是 Facebook 與 twitter 各種社交功能與外觀的顯示範例與分享代碼。

Facebook Share 的分享代碼

按鈕配置

分享

<a name="fb_share" type="button_count" href="http://www.facebook.com/sharer.php">分享</a><script src="http://static.ak.fbcdn.net/connect.php/js/FB.Share" type="text/javascript"></script>

方塊配置

分享

<a name="fb_share" type="box_count" href="http://www.facebook.com/sharer.php">分享</a><script src="http://static.ak.fbcdn.net/connect.php/js/FB.Share" type="text/javascript"></script>

Facebook Like 的分享代碼

標準配置

<iframe allowTransparency='true' expr:src='&quot;http://www.facebook.com/plugins/like.php?href=&quot; + data:post.url + &quot;&amp;send=false&amp;layout=standard&amp;width=450&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=tahoma&amp;height=20&quot;' frameborder='0' scrolling='no' style='border:none; overflow:hidden; width:450px; height:20px;'></iframe>

按鈕配置

<iframe allowTransparency='true' expr:src='&quot;http://www.facebook.com/plugins/like.php?href=&quot; + data:post.url + &quot;&amp;send=false&amp;layout=button_count&amp;width=90&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=tahoma&amp;height=20&quot;' frameborder='0' scrolling='no' style='border:none; overflow:hidden; width:90px; height:20px;'></iframe>

方塊配置

<iframe allowTransparency='true' expr:src='&quot;http://www.facebook.com/plugins/like.php?href=&quot; + data:post.url + &quot;&amp;send=false&amp;layout=box_count&amp;width=90&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=tahoma&amp;height=63&quot;' frameborder='0' scrolling='no' style='border:none; overflow:hidden; width:90px; height:63px;'></iframe>

twitter 的分享代碼

水平按鈕

<script src='http://platform.twitter.com/widgets.js' type='text/javascript'/>
<a class='twitter-share-button' href='http://twitter.com/share' expr:data-url='data:post.url' expr:data-text='data:post.title'>Tweet</a>

垂直按鈕

<script src='http://platform.twitter.com/widgets.js' type='text/javascript'/>
<a class='twitter-share-button' href='http://twitter.com/share' expr:data-url='data:post.url' expr:data-text='data:post.title' data-count='vertical'>Tweet</a>

參考資料

2011年8月7日

用 google-code-prettify 在網頁中嵌入代碼

作為一個以程式技術為主的網誌,文章中免不了得出現一兩段程式碼。原本我使用 githubgist 服務來將程式代碼內嵌到網頁([使用效果見此]),另一方面 gist 也可以用來當作是自己的小小代碼備忘錄,許多程式碼片段直接丟上去就好了,非常便利,可說是一舉兩得。

不過有時候只是想要顯示幾行代碼,這些代碼也許不具有完整性,如果將代碼一股腦兒地全丟上 gist,總有一天代碼庫會變成亂葬崗。所以除了 gist 之外,我也找了其他網頁貼程式碼的方案。原本前幾天已經物色好了 SyntaxHighlighter,打算趁週末有空時來實裝測試。結果因為在安裝前四處蒐集資訊,意外又發現到 google-code-prettify,看了一下立刻就變心決定改用 google-code-prettify。

其實就功能上而言,SyntaxHighlighter 遠遠勝過 google-code-prettify,之所以選擇了 google-code-prettify,最主要的原因就在於「簡單」。兩者的比較如下(分別簡稱為 GCP 和 SH):

  • 遇到過長的程式碼,SH 可以顯示出 Scrollbar,維持原排版;而 GCP 則會強制換行。
  • SH 預設有行號,GCP 也可加入行號,但不方便。
  • 兩者都支援顏色主題。包含預設的在內,SH 現有 7 種顏色主題,GCP 則有 4 種。
  • SH 支援 23 種程式語法,GCP 預設內建的也有 20 種左右。
  • 就安裝上,GCP 只要加入兩個檔案,就可以處理大多數的語言;SH 則除了得加入核心的 CSS 與 JavaScript 檔共三個檔外,還必須加入對應使用程式語言的 JavaScript。
  • 使用上兩者差異不大。SH 除了 <pre> 標籤外也提供了 <script> 的使用方式;GCP 則是可以省略語法指定,自動判斷。

由於我經常跨不同程式語言撰寫,因此 SH 在安裝上對我而言就顯得比較不便。雖然新版提供了 Autoloader 來動態決定要載入哪些程式語言語法的 JavaScript,不過我最後還是選擇單純一點的 GCP。GCP 對我而言最大的缺點就是沒有行號,我在 IDE 上寫 code 一定會打開行號顯示,不過反正網頁上顯示的代碼行數都不多,沒有行號這一點倒是還可以接受。

以下就是我的 google-code-prettify 安裝筆記:

Step 1.

google-code-prettify 首頁下載好檔案後,解壓放到自己的網路空間上。我是放到 Dropbox 的 public 資料夾下。

Step 2.

然後再修改自己網頁的範本。有兩個地方要修改,一個是在 </head> 標籤之前加上 css 與 javascript 的載入;另外一個是在 <body> 標籤內加上 onLoad 函式。

<head>
  <-- 中略 -->
  <-- 1. 在 /head 標籤前加入下面兩行 -->
  <link href="http://my.url.to/prettify.css" rel="stylesheet" type="text/css"/>
  <script src="http://my.url.to/prettify.js" type="text/javascript"/>
</head>

<-- 2. 在 body 標籤內加入 onload 設定 -->
<body onload='prettyPrint()'>
</body>

Step 3.

接下來只要在想要使用代碼的地方,用 <pre><code> 包起來,並且設定 class 為 prettiprint 即可。google-code-prettify 會自動判斷裡面的代碼是屬於何種語言。

<pre class="prettyprint">
#include <stdio.h>

int main(void)
{
   printf("Hello, world!\n");
   return 0;
}
</pre>

上面這段代碼的結果如下:

#include <stdio.h>

int main(void)
{
   printf("Hello, world!\n");
   return 0;
}

如果想要自己指定區塊內的程式語言,可以再加上 lang-*,其中 * 要替換成該程式語言的代碼。

<pre class="prettyprint lang-html">
  <-- HTML 的場合 -->
</pre>
<pre class="prettyprint lang-c">
  /* C 的場合 */
</pre>
<pre class="prettyprint lang-py">
  " Python 的場合
</pre>

目前支援的代碼有

"bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html", "java", "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh", "xhtml", "xml", "xsl"

看得出來是以程式碼的副檔名做區隔。基本上常見的幾乎都包含在裡面了。


參考資訊:

2011年7月30日

Eclipse 的常用快速鍵

我身為一個程式設計師,有個鍵盤在身邊,也很合邏輯。這個鍵盤呢,是我用來撰寫代碼用的,很合理吧?可話說回來,這扳子,啊不,這鍵盤如果只有拿來寫代碼,那可就浪費了;身為一個高生產力的程式設計師,應該充分活用鍵盤的各種功能,活用到甚至能夠取代大多數滑鼠的操作,那才叫專業。所以說,善用功能熱鍵就很重要啦,江湖上有本武功秘笈,書名叫做《程式設計師提昇生產力秘笈》,裡頭就有一段關於「奧義,鍵盤捷徑」的心法敘述:

......程式設計(除了使用者介面設計外)是文字性活動,所以,你應該儘可能把你的手放在鍵盤上。......你一整天都使用 IDE 建立程式碼,而 IDE 有大量鍵盤捷徑。全都學!使用鍵盤捷徑在原始碼內走動,一定比使用滑鼠快。 (P.30)

當然,沒有必要每個人都成為一代武林宗師,因此也沒有必要像上面說的一樣將每個鍵盤捷徑全部學起來。大多數人只要學個一招半式,就可以闖蕩江湖,應付高達八成以上的滑鼠操作。可是,功能熱鍵百百款,到底哪些才是常用需要記得呢?底下整理一些 Eclipse 上常用的熱鍵表:

編輯相關

  • Ctrl + Shift + F = 重新排版
  • Ctrl + Shift + M = 加入 import (加入游標所在類別所需的 import)
  • Ctrl + Shift + O = 整理 imports (掃描整個檔案,加入所需並刪除沒用的)
  • Ctrl + / = 切換註解(按一次加上註解,再按一次取消註解)
  • Ctrl + I = 修正縮排
  • Alt + Shift + ↑ = 擴大選取

游標或檔案定位

  • F3 = 跳到定義
  • Ctrl + E = 已開啟檔案清單
  • Ctrl + O = 開啟符號清單
  • Ctrl + J = 漸增式搜尋

除錯與執行

  • F11 = 以除錯模式啟動 (Debug)
  • Ctrl + F11 = 啟動 (Run)
  • F5 = 步進,深入一層 (Step Into)
  • F6 = 步進,往下一行 (Step Over)
  • F7 = 步進,回上一層 (Step Return)

重構相關

  • Alt + Shift + R = 重新命名 (Rename)
  • Alt + Shift + M = 提煉函式 (Extract Method)
  • Alt + Shift + L = 提煉區域變數 (Extract Local Variable)

如果覺得上面這些功能熱鍵還不夠看,當然也可以自己進去 Eclipse 的設定中去挖掘更多的指上神功。查看功能熱鍵列表的途徑要從選單列的 Window → Preferences 進入,接著就可以看到下面這張圖,然後按圖索驥,找到自己常用功能的熱鍵。

eclipse key binding

好啦,上面列出這許多的熱鍵,要怎樣才能有效的背下來呢?很簡單,不用背--最有效的記憶方法不是靠腦袋記,而是用身體去記。把常用功能熱鍵印出來貼到電腦旁邊,然後不斷的用、不停的用,直到每次要使用該功能時,腦袋想都來不及想手指就已經按出組合熱鍵,這樣就再也忘不掉了。(不過太久沒用的話,還是需要一小段時間來重新回復手感,只要一小段時間而已,真的。)

除此之外,當每次要使用選單列(Menu Bar)或工具列(Toolbar)上某樣功能時,停下來多想兩秒鐘:不要急著按下滑鼠左鍵,先看看選單文字或按鈕的提示上有沒有快速鍵的按法,有的話將手放開滑鼠,重新以快速鍵的方式完成自己的目的。久而久之,這些操作自然都會內化成為身體上的一部分。只要持之以恆,每日精進,減少手指頭在鍵盤滑鼠上切換的次數,那麼總有一天,我想,要達到「每小時幾十萬行程式碼上下」也不再是個夢想啦!

2011年7月28日

To Iterate is Human, to Recurse, Divine

今天偶然看到這句話,"To iterate is human, to recurse, divine.",無巧不巧,最近幾天的課程我也剛好在講解遞迴的概念。

說這句話的老兄是 L. Peter Deutsch,雖然他的姓寫作是「德意志(Deutsch)」,可是這位德意志先生卻是個道道地地的美國麻省人。Deutsch 在電腦界最主要的貢獻就是 GhostscriptArchie。Ghostscript 是可以用來生成 PDF 或是 Postscript 格式文件的軟體,從 1988 第一版釋出一直到今年 2011 橫跨了 23 個年頭,仍然持續開發維護中(當然維護者早已換人接手,不再是 Deutsch 了),也衍生了許多分支專案。

而關於另一項成就 Archie 可能聽過的人就比較少了,因為這是早年的一項網路服務,如同 Gopher 或是 News 一樣,早已淹沒在歷史的洪流中。在大家都還是以 FTP 作為主要下載方式的年代裡,Archie 可以整合不同匿名 FTP 站台的資訊,建立各站台擁有檔案的索引,然後使用者只要上連 Archie 網站,輸入檔名進行搜尋,就可以知道自己想要的檔案可以從哪個 FTP 站台下載。聽起來很像搜尋引擎做的工作不是?沒錯,Archie 某種程度上可說是網頁搜尋引擎的前身。早在 Google 甚至 Yahoo! 出生之前,Archie 就已經在 Internet 上運作好一段時間了。對這段歷史有興趣的可以看看這篇:The first search engine, Archie.

回頭來看看篇首這句:

"To iterate is human, to recurse, divine"

這句到底代表什麼意思,著實讓我推敲了很久。先來看看網路找來的兩個我覺得不錯的翻譯(原譯者均不明):

“迭代(iterate)者为人,递归(recurse)者为神。”

「遞迴(recurse)只應天上有, 凡人該當用迴圈(iterate)」

同樣一句話,將其放在不同情境下會有截然不同的解讀。這句的意思到底是要說「我們應該放棄平凡的作法,盡量使用遞迴,以追求神的境界」呢?還是想表達「遞迴這種作法太神乎奇技了,我們應該用簡單、平凡,一般人都可以接受的作法,以迴圈來實現」呢?

我參透不出這句話到底是推崇遞迴還是鼓勵迴圈。不過以我的經驗而言,遞迴雖然一開始很容易讓人腦筋打結,可是當熟悉遞迴之後,許多複雜的處理都會變得簡單明瞭。許多程式機制的實作擺脫不了遞迴,比方說遍歷某資料夾下的所有子資料夾與檔案、迷宮路徑的搜尋,或是 AI 決策樹的判斷,使用遞迴來寫可以達到事半功倍的效果。

當然,所有的的遞迴都可以改寫成迴圈形式,改寫為迴圈形式通常也可以獲得效率上的提升,因為遞迴層層呼叫的過程中不停將資料塞入堆疊又從堆疊取出的手續太耗成本,遠不如迴圈以少數幾個變數就可以控制完整的流程。但是將遞迴改寫成迴圈的形式往往會失去邏輯的簡潔與結構的優雅。

寫程式經常就是遇到這種兩難:要嘛對電腦好,讓它少算一點,少用點空間;要嘛對人好,電腦多做點工,可是人類看起 Code 來輕鬆(話說遞迴也不見得都比迴圈式的改寫好懂就是)。因此,針對同一件事情,該用遞迴解還是迴圈解好呢?我想,選擇自己與他人都容易理解的方法去做,那就對了。

2011年7月26日

UIGestureRecognizer 的共存

在 iPhone 或 iPad 的開發中,除了用 touchesBegan / touchesMoved / touchesEnded 這組方法來控制使用者的手指觸控外,也可以用 UIGestureRecognizer 的衍生類別來進行判斷。用 UIGestureRecognizer 的好處在於有現成的手勢,開發者不用自己計算手指移動的軌跡。UIGestureRecognizer 的衍生類別有以下數種:

  • UITapGestureRecognizer
  • UIPinchGestureRecognizer
  • UIRotationGestureRecognizer
  • UISwipeGestureRecognizer
  • UIPanGestureRecognizer
  • UILongPressGestureRecognizer

從命名上不難了解這些類別所對應代表的手勢,分別是 Tap(點一下)、Pinch(二指往內或往外撥動)、Rotation(旋轉)、Swipe(滑動,快速移動)、Pan (拖移,慢速移動)以及 LongPress(長按)。這些手勢類別在使用上也很簡單,只要在使用前宣告並掛到對應的視圖(UIView)元件上即可。

問題來了。有些手勢其實是互相關連的,例如 Tap 與 LongPress、Swipe 與 Pan,或是 Tap 一次與 Tap 兩次。當一個 UIView 同時掛上兩個相關連的手勢時,到底我這一下手指頭按的要算是 Tap 還是 LongPress?如果照預設作法來看,只要「先滿足條件」的就會跳出並呼叫對應方法,舉例來說,如果同時註冊了 Pan 跟 Swipe,只要手指頭一移動就會觸發 Pan 然後跳出,因而永遠都不會發生 Swipe;單點與雙點的情形也是一樣,永遠都只會觸發單點,不會有雙點。

那麼這問題有解嗎?有的,UIGestureRecognizer 有個方法叫做 requireGestureRecognizerToFail,他可以指定某一個 recognizer,即便自己已經滿足條件了,也不會立刻觸發,會等到該指定的 recognizer 確定失敗之後才觸發。以同時支援單點擊與雙點擊的作法為例,程式碼如下:

如此一來,在第一下點擊後,如果有迅速點擊第二下,就會觸發 doubleRecognizer;反之要是隔了一小段時間,造成 doubleRecognizer 發生 fail,就會回頭觸發 singleRecognizer 了。

我的程式語言之路

從大學以來,這十幾年的工作與生活總與程式設計脫不了關係。前前後後寫了不少的 Code, 也接觸過許許多多不同的 Programming Language。這邊就來記錄一下自己現在還有印象的程式語言,也許十年之後再來回顧,又是另一種不同的想法吧。

QBasic

高中時候獲得人生的第一台電腦,當時還是 DOS 的年代,每個裝了 MS-DOS 的電腦都會內附 QBasic。還記得用 QBasic 寫過一些簡單的遊戲,像是 1A2B、迷宮產生之類的,但是真要說自己寫的其實也不是,很多都是照著當時雜誌(例如「第三波」)上的代碼 key 進電腦中而已。

Turbo C++

說真的,我已經不記得是 Turbo C 或是 Turbo C++ 了,但可以肯定的一點是,我當時一定只用到 C 的語法概念,沒有物件,只有單純的流程控制,對指標有似懂非懂的感覺。其實嚴格說起來,Turbo C++ 只能算是種 IDE,不算程式語言。

Borland C++ Builder

這也是 IDE,不過因為同樣的 C++ 語言在不同的 IDE 與不同的基本函式庫下會呈現出截然不同的個性,所以我就單列了。記得在我還是學生的時代,BCB 的出現帶來革命性的軟體開發方式,只要簡單拉一拉就可以有個像樣的視窗程式。當時蔚為風潮,我也趕流行玩了一陣子,不過也沒拿來寫過什麼東西就是。

Visual Basic

很簡單的程式語言。我曾經用 VB 寫過一個「光榮三國志臉譜瀏覽程式」的工具,可以讀取《三國志》四代、五代的頭像檔案。可惜現在原始碼與二進位檔都沒有留下,只有留下當時在巴哈姆特發佈時的帖子。如果有人看到這篇文章,又碰巧有留當年的程式的話,歡迎跟我聯絡。也許哪天我心血來潮會再重寫一遍也說不定。 ;-)

Common Lisp & ML

這兩個都是因為學校的課程而接觸的。剛開始學 Lisp,腦袋會打結,就是一層又一層的括號,常見的數學運算也都得換成前置式;不過作業寫到後來我還蠻喜歡寫 Lisp 的感覺。ML 也是,跟一般我們常見的 C-like 語法結構都不一樣。那時候我還蠻愛這兩個語言的,一直到畢業後的幾年間,我只要重灌電腦完要重新安裝軟體時,我就會把這兩個程式語言給裝進去,就像現在我會安裝 Python 一樣。

ASP

大四時接了一個學姊的家教網案子,那時候用的開發語言就是 ASP。不過說真的現在我對 ASP 都忘光光了。附帶一提,那個網站現在還活著,當然已經轉型了就是,不再是以媒介家教資訊為主。

Java

學生時代有寫過一些 Java applet,那時候的網頁很流行水波效果,幾乎十個個人網站有八個的 banner 都要來一下水波盪漾。Applet 也是淺嚐個大概而已,倒是 Java Servlet 因為工作的關係寫了蠻長久一段時間,從學生時代到退伍後都還有在接觸。話說事隔多年後,因為最近工作的關係,又開始跟 Java 打交道了。

HTML & JavaScript

還在唸書時因為有協助維護一個購物網站,因此免不了要碰到 HTML 與 Java Script 的撰寫。當時那個購物網站使用的技術,有一部分是上面提到的 Java Servlet,另外也有用到 PHP 的部份。之後過了好幾年,有一個跟朋友合作開發 Facebook 遊戲的機會,在那次開發中又重新溫習了一次 Java Script,並且大量採用 Ajax 技術。可惜那個遊戲在發佈之前就胎死腹中了。

PHP

最主要就是上面提到的購物網站與 Facebook 遊戲這兩個案子用到,不過卻前前後後持續寫了蠻長久的一段時間。維護購物網站的時後基本上都還是程式碼硬幹,到了寫 Facebook 遊戲的時候,就有現成的框架了,我選了一個叫 CodeIgniter 的框架,大體上類似 ROR 的寫法。其實一開始選的是 CakePHP,比較完整,不過真的是太龐大了,所以才換成 CodeIgniter。此外,由於以前經常安裝討論區、部落格、Wiki、購物車等網站套件,其中許多是 PHP 寫的,常常需要 hack 部分代碼,因此對 PHP 還算蠻熟悉的,有陣子甚至拿 PHP 當 Shell Script 來使用,用來解決手邊的小問題。

SQL

說到網站程式就不能不提到資料庫。前前後後接觸過一些不同的資料庫,學生時代在 IBM 打工時是 DB2,前面提到的購物網站是 MySQL,進了遊戲公司之後,陸續又接觸到 PostgreSQL、Microsoft SQL Server,Oracle。其實單就 SQL 來看的話都大同小異,各資料庫 Server 之間最大的差異性還是在 Server 的管理與調校上,以及各種千奇百怪的程式介接函式庫寫法。

Shell Script

除了用 PHP 當 Shell Script 外,在我還在第一家遊戲公司時,由於是在 Linux 平台上開發的關係,也用 BASH 寫了不少方便日常工作或是開發的 Script。有少部分的代碼用 Perl 寫,用 Perl 寫起來很快,不過寫完看起來真的像天書一樣,真的是「寫完即丟」的語言。在 Windows 上,也曾經用 Batch 檔或是 Power Shell 寫過一些臨時性的小工具。

C++

進入遊戲公司後,幾乎就一直過著與 C++ 分不開的生活。早先是在 Linux 下寫 Server,能用的就是 Emacs 或是 Vim,後來換了公司,改用 Visual C++ 寫,一開始我還真的很不習慣,這麼複雜而多功能的介面,有時常常不曉得從哪邊開始下手。雖然在念書時學過,但我是從進遊戲公司之後,才真正重新認識了 C++,學到物件導向、Template、設計模式、重構等概念。當然,上面有些概念是跨語言通用的,不過因為 C++ 是我這幾年來長期接觸的語言,自然也成為前述幾個概念的學習媒介。

C++ 是個頗具爭議性的語言,他使用者多,但批評者更多,C 語言的陣營批評 C++ 不夠簡潔、純粹,STL 更是把許多工作變成讓人摸不著頭的黑箱;反之 Java 或 C# 的支持者又覺得 C++ 不夠完善,要寫個功能還要到處找函式庫,同個功能可能還有好幾種不同的函式庫,不同的實作與不同的使用概念,令人眼花撩亂。我自己是覺得,C++ 雖然亂,雖然我也對此感到困擾,但是也正因為他的兼容並蓄,使得各種各樣的想法與實作都能在上面獲得實踐。不過話說回來,對於產品開發而言,有時候工具還是單純點好。

Auto Hotkey Script

為了玩 Facebook 遊戲更「方便」而去學的程式。有寫了餐城(Restaurant City)的自動撿垃圾、自動到別人家評分,以及 Farmville 的自動種植、收割、耕地等功能,Mafia Wars 的連續任務。這些工具都是自娛,沒有對外釋出。隨著社群遊戲不斷的改版,這些工具也早就失效不能使用了。

Lua

在之前待過的公司中有用過,之後自己出來做的案子也有用。雖然如此,自己還是覺得對 Lua 的使用還不夠熟。曾經有寫過一個專案,使可以整合 C++ 與 Lua / Python / Squirrel 這三種 Script Language,目的是可以從 C++ 呼叫寫在 Script 的函式,也可以反過來。不過當初只寫了一個方向(C++ 呼叫外部),反過來的方向由於各 Script 語言存在的差異較大,自己的能力也不夠,就沒繼續開發下去了。

Python

這語言已經成為我這一兩年來的最愛了。在 Script Language 的領域中,一開始我是對 Lua 比較有興趣的,畢竟公司專案在用,而且 WOW 的 Custom UI 也都是用 Lua 撰寫,有 Billizard 的光芒加持,自然讓人不得不多看 Lua 幾眼。不過自從寫過 Python 的 Code 之後,我發現寫 Python 的過程可以獲得一種純粹的程式撰寫樂趣,我面對的是「程式所要解決的問題」本身,而不再是陣列、記憶體配置、指標、堆疊等等這些瑣碎的雜事。去年開發一個簡單的動畫編輯器,就是以 Python + wxPython 作的;而最早接觸 Python 的起點呢?喔,那是為了寫一個 Travian 的找資源點的工具,比較了幾個語言後發現用 Python 來抓網頁資料進行解析最為方便,於是就一頭踏入 Python 的思考領域了。

NSIS (Nullsoft Scriptable Install System)

最近才開始摸的東西,是用來寫安裝程式的語言。除了一開始入門門檻稍高外,不算太難,只要跨進去後剩下的就簡單了。之所以說一開始稍難,是因為最簡單的安裝軟體也要做許多事情,畢竟安裝軟體可不像其他語言只要秀秀 "Hello World" 就算完成第一個程式了。NSIS 也有 function 跟 macro,不過 function 沒有傳入參數,反正所有變數都是全域,也就不用傳入什麼了;如果真的需要傳入參數的話,倒是可以用 macro,雖然意義上不是,但程式碼看起來更接近傳參數的函式。這算是最近寫 NSIS 的一個小小心得吧。

Objective-C

這是目前正在進行的專案所用的語言。如果熟悉 C++/Java/PHP 這類 C-like 的語言,要學 Objective-C 真的很快。比較大的不同在於 message 的概念,前面的幾個語言不管是 function 或是 method,都是圓括弧呼叫的方式,在 Objectiv-C 中,函式的呼叫變成了訊息的傳遞,而且每個變數都必須寫出變數名字。剛開始看的確會有些彆扭不習慣,但是徹底改用「訊息傳遞」的角度去思考理解的話,其實 Objective-C 的這種寫法還蠻可愛與口語化的。

後記

看了一下 TIOBE Programming Community Index for July 2011,前十名的程式語言中,除了 C# 之外,有九個我都接觸過或多或長的一段時間。其實之前為了研究 XNA,也有稍微看過 C# 的 code,不過稍微看看也不算寫過就是。但是 Windows Phone 的開發免不了得靠 C#,或許再不久的將來有機會寫 C# 也說不定?

Related Posts Plugin for WordPress, Blogger...