The Old Blog Archive (Traditional Chinese), 2004-2009

在一種想砍掉重練的 mood (快要進入 mode)

原本這個標題是要留到 blog 重練時用的(如果真的有那麼一天)。沒想到終於有力氣重審自己的第一個主要的Mac/Objective-C程式計劃後,竟然突然進入一種想砍掉重練的mood。命名得亂七八糟、太多重覆的code、風格的不一致。只有一個糟糕可以形容啊。不行不行。

Ruby Tuesday: 2007/5/29 (二) 在 OPCafé

每雙週二舉行的 Ruby Tuesday,5/29 (二) 同樣在新竹市中心的 OPCafé 舉行。

這次的 Ruby Tuesday ,我請來 b6s 來為我們客座講解 Apache Lucene 的基本原理。Lucene 是以 Java 寫成的全文搜尋程式庫,可說是最普遍的 search solution。由於 Ruby 的 Ferret 是根據 Lucene 的設計來實作,因此在基本概念、術語、特性上,都有和 Lucene 貼近的地方。b6s 對於全文搜尋──以及全文搜尋所根基的諸多自然語言處理的理論──瞭解深入。我想如果能讓大家對於 tokenizing, analysis, indexing 等概念有更清楚的認識,相信選用 web app 的搜尋方案時,會能更精準找到自己要的,以及做出正確的 trade-off 決定。

除了 b6s 主講 Lucene,我會補充說明 Ferret,尤其是 acts_as_ferret 這套 plug-in 的使用方法。

歡迎大家屆時來 OP !

Cocoa Tuesday: 2007/5/22 星期二 20:00在OP

這週二是 Cocoa Tuesday,打算來講一些 Cocoa 繪圖以及文字繪製的基礎,地點一樣是在OPCafé

acts_as_ferret: Rails全文搜尋快速上手(與中日韓文支援)

Here are some code snippets that I use to add CJK (Chinese, Japanese and Korean) characters support to Ferret and acts_as_ferret.

(Update: lingr.com has released their multilingual analyzer, see http://blog.lingr.com/2007/05/a_new_plugin.html for detail).

相信許多鐵道迷都聽過雪貂(Ferret)。雪貂是一套根據Lucene所開發的全文搜尋引擎。裝上了「化身為雪貂」(acts_as_ferret)這套plug-in之後就更厲害了,任何ActiveRecord model只要加上輕量之人最愛的神秘一行,瞬間就具有了全文搜尋能力。

Ferret是用C寫成的,用語和基本觀念與Lucene一致。因此對Lucene有認識的朋友應該很容易上手。雖然說化身為雪貂很好用,不過O’Reilly的Ferret一書仍有一讀的必要。該書最後還介紹如何配合其他plug-in來index諸如PDF, JPEG EXIF等metadata,幾乎可以寫一套小型的Mac OS X Spotlight。而該書對於Ferret的構成、內部運作原理、performance tuning的介紹,也相當實用(而且,不需要先學Lucene;我也還在研讀這一部份就是了……)。

以下是我用的 RegExpAnalyzer,僅僅很簡單的把歐語的單詞拆開、數字拆開,中日韓文則以字元方式來索引。這種簡單的中日韓文tokenizing在搜尋精確度不要求高的場合,大體能用。要更好的搜尋結果,或是要做到同音字搜尋、簡繁搜尋,當然就需要更複雜的 Analyzer。

請找個地方填入以下的 regex 跟 Analyzer:

GENERIC_ANALYSIS_REGEX = /([a-zA-Z]|[\\xc0-\xdf][\\x80-\\xbf])+|[0-9]+|[\\xe0-\\xef][\\x80-\\xbf][\\x80-\\xbf]/
GENERIC_ANALYZER = Ferret::Analysis::RegExpAnalyzer.new(GENERIC_ANALYSIS_REGEX, true)

然後在想要加入搜尋的 model 裡加入:

acts_as_ferret({:fields => [ FIELDS_YOU_WANT_TO_INDEX ] }, { :analyzer => GENERIC_ANALYZER })

之所以不把 GENERIC_ANALYZER 放在 acts_as_ferret 裡,除了可重用性的原因,另外還避免掉在 Mongrel + Rails development mode 時可能造成的 bus error / segmentation fault (原因不明)。

總之,只要做完這件事,就可以:

Model.find_by_contents("hola")

acts_as_ferret很聰明,如果是第一次使用,會幫你把這個data model所用table全部讀一遍,建立必要的全文索引。之後所有的 CRUD 動作只要透過這個 model ,「化身為雪貂」會幫你做完所有該做的 Ferret indexing 動作。

先前有一些中文論壇提到用 /./ 來處理中文斷字(說「斷詞」或「分詞」有誤導之嫌)。雖然 Ruby 的 regex engine 在 $KCODE 設為 utf-8 時,可以正確地以 /./ 來掃描 Unicode 字元,但是這樣的作法是有問題的。英文詞因此會被斷成一個字元一個字元。而,單純用 [a-zA-Z] 則忽略了歐語,這是不夠的。

偏偏 Ruby 的 Unicode 支援只做了一半,不像 Perl 可以用 /\x{80}-\x{7ff}/ 的方式來表達 Unicode range,所以我們得祭出 jcode.rb 裡處理 UTF-8 的 regex (也就是利用 UTF-8 的特性),來找出實際上為 U+80 ~ U+7FF 以及 U+800 ~ U+FFFF 的字元。當然,> U+FFFF 的字元這裡並沒有處理,而且這個方式其實過於簡化。

但總之這是可以用的方法。如果要測試或改善 regex ,可以使用Ferret一書中第65頁所列的以下方法來測試:

def test_token_stream(token_stream)
  puts "Start | End | PosInc | Text"
  while t = token_stream.next
    puts "%5d |%4d |%5d   | %s" % [t.start, t.end, t.pos_inc, t.text]
  end
end

然後在irb中:

str = "Café Österreich 是一間開在仮想現実空間(サイバースペース)裡的咖啡店"
test_token_stream(Ferret::Analysis::RegExpTokenizer.new(str, GENERIC_ANALYSIS_REGEX))

就可以看到 RegExpTokenizer 執行的效果。

OpenVanilla subversion repositoy搬家

昨天(台北時間 2007/5/15 中午)我們在 OpenVanilla 討論區中發布了 OpenVanilla subversion repository 的搬遷通知。今天早上全部的 subversion repository 已經搬遷完成。

我們新的 primary repository 位於 http://openvanilla.googlecode.com/svn/。新的計劃頁面在 Google Code Project Hosting上。

先前在 OpenFoundry 上的 repository 將改為 read only mirror。原先的計劃頁面也有進行整理的必要。

Google Code 的 subversion 為 1.4 版。配合最近版本的 svk (2.0.1),已經可以將全部的 revision history 同步到自己的 depot 中,先前在某幾個版本會斷掉的問題應不會再出現。

Ruby Tuesday的投影片和錄音: Build Your Own Gem

謝謝大家前來本次 Ruby Tuesday,投影片錄音已經可以下載了。不過有一個地方講錯了一定要修正,那就是 gem install 時是可以順便做 test 的,只是預設為關閉。

Ruby Tuesday: 5/15 星期二 20:00 在 OP

又到了每雙週一次的 Ruby Tuesday。這一次的 Ruby Tuesday 我打算介紹 gem 的包裝方式,主要是利用Dr. Nic寫的newgem generator來大幅簡化gem的包裝工作。我會介紹ObjectiveFlickr的包裝過程,並計劃在當天實際打包另一個可做為gem的module,來發布到RubyForge上。

先前有朋友問到,在新竹舉辦,實在太遠的問題。嗯,我以一個長到這麼大都一直住台北的人的立場,新竹的確是稍遠了些。不過地理學上有所謂的「空間輻合」(space convergence,應該是這麼講沒錯吧,我的地理學已經生鏽了),其中一個意思是說,因為兩城市間有便利且頻繁的交通,使得空間距離上比較遠的兩地,反而實際上所費的總交通時間,比介於其中的鄉鎮要少。台北到新竹,不管是坐火車,或從台北車站附近搭客運,都可以很快到新竹車站一帶,而從新竹車站步行約 15-20 分鐘就可以到 OP 了。以先前的舉辦經驗,只要在 22:00-22:30 左右告一段落,搭接近末班車回台北後,要搭到近末班的捷運也是沒問題的。

地點一樣是在新竹的OPCafé。到時見!

Cocoa Tuesday: 星期二5/8 20:00在OP

又到了每雙週二的Cocoa Tuesday。今次的Cocoa Tuesday,我計劃簡單介紹關於Objective-C、一點 Cocoa 的歷史,以及 Foundation classes (NSObject, NSArray, NSDictionary 等諸 NS* 開頭的 class) 的簡單用法。

地點一樣是在新竹市的無線網路免錢的有很多漫畫和小白兔唱片最重要還有咖啡好喝及隱藏菜單的OPCafé

五年一度的documenta、德國Kassel開催

因為讀到一篇關於實踐大學講師曾御欽的報導,才驚覺今年正好又是五年一度documenta開催年。1997年夏天我在布萊梅混了一個月,結果竟然沒抽空去。那一年幾乎每一班德國高速列車ICE車身都漆上了documenta X(當年是第十屆)字樣,其做為歐洲藝術盛事可見一斑。

雖然歐元貴得離譜,不過今年還有另一項和技術有關的盛會也在德國辦。不知道去得成去不成,先在這裡記一筆,當成是目標吧。

Ruby Tuesday: 5/1 20:00在OP

這一週的 Ruby Tuesday,我們來討論「每次都得重寫的 login component」,以及可能的幾種解痛之法。另外從 login component 似乎也見微知著。Ruby on Rails 雖然很熱,Rails wiki 的狀態、幾個「關鍵 plug-in」遲遲跟不上 Rails 本體更新速度等事,似乎也挺令人擔心的。歡迎大家屆時到 OPCafé 坐坐。:)

« Previous PageNext Page »