12/26/2008

File_Column 在 Rails 2.2 遇到問題以及解法

這裡找到的解法,File_column 在升級 Rails 2.2 會遇到問題

uninitialized constant FileColumn::ClassMethods::Inflector 


解決方式就是找到 vender/plugins/file_column/lib/file_column.rb 的 619行

my_options = FileColumn::init_options(options,   
Inflector.underscore(self.name).to_s,
attr.to_s)


改成

my_options = FileColumn::init_options(options,
ActiveSupport::Inflector.underscore(self.name).to_s,
attr.to_s)


即可。主要原因是 Rails Core 漸漸有 Namespace 概念(不是本來就要有了嗎XD),所以之前可以 work 的 plugin code 現在都要修改成比較好的寫法。

12/24/2008

金剛合體:Merb 將要 merge 到 Rails 3

我以為 Rails 2.2 已經很有創意了,弄出很多新東西(or 應該做的東西) ,Rails 3 到底要做啥東西才能夠讓人家驚訝了呢?噹噹,我發現到 Rails 還是嚇到我了 。

Big news 就是 Merb 跟 Rails 3 預計在 2009 的 Rails conf Merge 起來,Merb 作者 wycats( Yehuda Katz)會加入 Rails Team。請注意,我知道很瘋狂,不過這個消息已經經過 Rails And Merb 雙方證實了。

DHH 指出這次的 Merge 有幾點工作要做

  1. Rails core:Rails 是一個 full stack framework ,不過他要參考 merb ,讓人很簡單的做出 rails myapp–core 和 rails myapp—flat
  2. 效能強化
  3. Framework 解構:雖然 Rails 預設依舊是 ActiveRecord 當 ORM,不過你也可以選擇 data mapper,Sequel,Template 可以選擇 HAML,AJAX 可以選擇 jquery
  4. Rigorous API:反正就是要解決 Rails 一升級 plugin 就炸掉的問題

怎麼看起來像是又生出一個 Merb ?

我來猜猜,DHH 認為 Merb 社群長久以來的堅持是對的,而 Rails 社群漸漸走錯路, DHH 眉頭一皺,認為案情並不單純,利用自己還很龐大的力量吃掉 Merb ,然後順便導正 Rails 該走的路。

It is not good news , and it is also not bad news,It's AMAZING news。


12/22/2008

Ruby Memory Leak 巨大問題以及解決方式

Ruby Memory Leak 一向是一個難以解決的議題,不過在今年 11月12日的 Mailing List 裡面有人提出一個重要的問題, Ruby 的 callcc 在使用中產生相當明顯的 Memory Leak。後來有高手 Brent Roman 發表他的發現。他原本再 ARM CPU 上面開發他的 Ruby Robot 程式(Ruby 1.6.8),他的機器人上面只有 32 MB 的 Memory,不過他的 Ruby 程式一天就會吃掉 20MB 的 Memory,經過他的 hack ,現在他的 Ruby 程式已經穩定在 10MB 以下,他發現 Ruby Memory Leak 很大部分在於 pointer ,跟 callcc 的使用上,Javaeye 上面有對於這個問題的詳細中文翻譯


Matz 知道之後,相當鼓勵 Brent 將他的 Patch 放到 Ruby 上面,如今他的 Patch 終於發佈,他是根據 Ruby 1.8.7-p72 做的 Patch ,又由於他在 Monterey Bay Aquarium Research Institute工作,所以叫做 1.8.7-p72 MBARI Patch,目前處於 Alpha 版本。他發現經過他的 hack 之後,對於 Memory Leak 上有相當大的解決。根據他的用 Ruby 預設的 Test Case 的結果,他發現 Memory 消耗從 97MB 降低到 57 MB,JavaEye 也利用他們的程式做測試,Javeeye Fcgi Memory 消耗量從 129MB 降低為 99MB。


相當不錯的結果,期待納入 Ruby 1.8.7 的那一天。


12/16/2008

Rails 2.2 在 Windows 上面有關 mysql Gem 的問題

今天要幫公司同事灌 Windows 上面 Rails ,發現安裝 mysql gem 出了點問題 ,本來是不用管,直接使用 Rails 附帶的 Mysql, 不過自從 Rails 2.2 之後,Rails 原本附帶的 mysql adaptor 已經移除掉adaptor,所以被迫得安裝 MySQL Gem 。

The bundled mysql.rb driver has been removed from rails 2.2. Please
install the mysql gem and try again: gem install mysql."
當我 gem i mysql,本來是沒問題的,不過現在不知道 gemspec 那裡改壞了,導致出現問題
Installing ri documentation for mysql-2.7.3-x86-mswin32...
Installing RDoc documentation for mysql-2.7.3-x86-mswin32...
ERROR: While generating documentation for mysql-2.7.3-x86-mswin32
... MESSAGE: Unhandled special: Special: type=17, text=""
... RDOC args: --op
所以第一個問題解法就是不搞 RDOC,直接使用 gem i mysql --no-ri --no-rdoc 安裝

當我以為已經解決的時候,沒想到出現第二個 Error
This error occurred while loading the following files: mysql
靠,Rails 2.2 + Windows 還真多災多難,解決方式根據這裡,裡面說到要把 MySQL 帶的 libmysql.dll 複製一份過去到 ruby\bin 底下
copy mysql\bin\dll\libmysql.dll ruby\bin\
我使用的是 Instant Rails ,所以 MySQL 跟 Ruby 都放在同一個資料夾下面,如果安裝方式不同請自行處理。


10/26/2008

Rails 2.2 :多個願望一次達成...

購物專家:來來,我們現在請到 Rails 副總來本購物台,想請問副總對於這次 Ruby on Rails 2.2 來本台銷售,帶來了什麼好康。

副總:這次的 Rails 2.2 可以說是本 Rails 產品史上最大的升級,可以說是把所有想的到聽的到看的到的問題都一次解決,保證這次不買你就是笨蛋,還去寫 PHP 或是 Java 只能祝福你。

購物專家:啥,那麼可怕,那我想問問,有關之前被人詬病的 Rails 國際化的部份有何加強。

副總:記得上次我們來的時候怎麼講的?Rails 要國際化必須要 Gettext 或是 Plugin 來解決對不對。今天帶來的第一個優惠, Rails 2.2 直接內建 i18n 給你。如果有問題的話,請到Rails i18n來看看怎麼實作。基本上是寫一個 yaml 就可以解決了。

(罐頭歡呼聲)

購物專家:什麼,直接內建 i18n ,那其他 Framework 不是少了一個古老的暴點可以笑 Rails 了嗎?你們上面業績衝的很兇歐,優惠送那麼大。那以前最讓人詬病的效能問題呢?

副總:抱歉,其他家公司,你們災洗了。我們這次直接升級到 Ruby 1.9,讓你們享受 19 倍的效率提昇。(註:購物台都是隨便唬爛的,有提昇是沒錯,有沒有 19 倍就不知道XD)

(罐頭歡呼聲)

購物專家:什麼什麼,你們直接支援效率打敗 Python 2.5 的 Ruby 1.9 呀,那不就是筆記型電腦加 Ram 再加 ssd 這樣誇張歐。這樣你們不會獲利下降嗎?

副總:沒關係,只要可以服務購物台,我們可以流血犧牲

購物專家:導播,各位觀眾,我已經快受不了,那麼好的優惠,那麼好的內容只在今天的 XX 購物台。現在電話所有線路忙線中,請改撥語音專線可以優先訂購。副總,已經端出那麼多了,還有啥好康的?

副總:還有還有,我們改寫 ActiveRecord 了,支援 connection pool 摟,並且是 ThreadSafe 了。只要在 config/database.yml 裡面加上

development:
___adapter: mysql
___username: root
___database: sample_development
___pool: 100
___wait_timeout: 10

就等於以 100 connection 讓 model 讀讓你取,效能提昇直接上看 100倍 (註:購物台都是隨便唬爛的,有提昇是沒錯,有沒有 100 倍就不知道XD)

(罐頭歡呼聲)

購物專家:現在耳機傳來導播的聲音,現在我們備貨數量已經真的真的很少了,大家太踴躍了,記得撥打語音專線可以省一百塊歐。副總你們還有啥優惠嗎?

副總:我們加入了 HTTP 的 last modified since 的 support,讓上次沒有修改過的內容就直接回傳一個 empty response 回去。原本是要回傳幾百K的東西,現在至需要回傳 0 K ,效能提昇直接上看無限大(註:購物台都是.....算了,懶得講了XD )

(罐頭歡呼聲)
(罐頭歡呼聲)
(罐頭歡呼聲)

副總:ㄟㄟㄟ,導播,我的購物專家勒?

導播:他太激動了,回去學習 Ruby on Rails 了。

副總:ㄟㄟㄟ,那麼猴急,我還沒講完勒,http://guides.rubyonrails.org 上線了,可以直接上去看一些 online guilde。



言歸正題,此次的 Rails 2.2 真的是超乎想像的加碼再加碼,修正了很多以前的問題,也加入相當多新的功能。

1. i18n
2. Ruby 1.9
3. connection pool
4. thread safe
5. etag and last modified since

真的可以說是史上最大的升級 XD

6/25/2008

Python Hackthon 遭到保護動物組織的抗議

http://www.javaeye.com/news/2697

http://techfaux.com/2008/06/17/peta-targets-computer-programmers-with-string-of-bizarre-protests/

間單講就是好好的 Python Hackthon 聚會,闖入一堆 30位女生,突然全部脫光衣服,然後舉牌子「How many lives just for a coat?」,意思是要殺掉多少蛇才能有一件蛇皮大衣。

這些天兵似乎還不知道自己在幹麼,她們大聲疾呼「We know what they’re doing in there. They’re hacking pythons. It’s barbaric and we won’t leave until the last snake has been saved」,秀才遇到兵,有理說不清。


改天 Ruby 聚會也有一堆人進來抗議,「停止虐待採紅寶石的勞工」怎麼辦....



6/06/2008

Rails 2.1 新特色:打包 Gem

顧客:老闆, Web 2.0 網站一份,Rails 要 2.1 的,還有幫我加香菜,還有所有的 Gem Package 都要包在一起,要快點,等等 10分鐘要上 Production Server。

老闆:好好好,馬上來,要不要順便叫個啤酒呀?

Rails 2.1 加入了一個新功能 Gem Dependencies ,相當的優。像是上述需求,只需要下達

$ rake rails:freeze:edge
$ vi config/environment.rb
$ rake gems:unpack
$ rake gems:build
即可完成將 Rails 原始碼,Gems 原始碼包入到 Rails app folder 裡面,這樣 deploy 超方便呀。

以下是詳細解說

$ rake rails:freeze:edge
把現在的Rails Version 打包入 vender/rails/

$ vi config/environment.rb
把所有有關的 Gem package 加入設定檔

Rails::Initializer.run do |config|

# Require the latest version of haml
config.gem "haml"

# Require a specific version of chronic
config.gem "chronic", :version => '0.2.3'

# Require a gem from a non-standard repo
config.gem "hpricot", :source => "http://code.whytheluckystiff.net"

# Require a gem that needs to require a file different than the gem's name
# I.e. if you normally load the gem with require 'aws/s3' instead of
# require 'aws-s3' then you would need to specify the :lib option
config.gem "aws-s3", :lib => "aws/s3"
end



$ rake gems:unpack
把所有的 config 裡面設定相關的 Gem Package 都打包入 vender/gems/

$ rake gems:build
非一定要用,只是如果你相關的 gem package 不一定是純 Ruby Code,有些會相關一些 C Lib,這時候就可以用這個指令來 build native gems。



6/05/2008

Gettext 在 Rails 2.1 下面的問題

Gettext 1.19 遇到 Rails 2.1 會發生以下的問題
NoMethodError (undefined method `file_exists?' for #):


解決方式就是寫一個 config/initializers/gettext.rb

require 'gettext/rails'
module ActionView
class Base
delegate :file_exists?, :to => :finder unless respond_to?(:file_exists?)
end
end



重起即可。

5/01/2008

Rails 2.1 RC Release

Rails 學習之路最困難的一件事就是,社群活力太強,改版太快了。Rails 2.1 RC Release了。請到Rails最新時尚的 github 去取用。

4/22/2008

把某資料夾的 UTF8 檔案轉成 Big5

不要問我為何如此,反正 TextMate + 只能用Big5的Project 造成的。


pwd = `pwd`.chop
all_files = `find app -type f -not -regex ".*.svn.*"`
all_files.each do |file|
old_file = pwd+"/"+file.chop
new_file = pwd+"/big5/"+file.chop
`iconv -f utf-8 -t big5 #{old_file} > #{new_file}`
end




4/12/2008

Passenger :Mod_rails for Apache 終於出世

這是 Rails 登基的最後一塊基石嗎?

不知道說了多少次,Apache 上面沒有 mod_rails,不能像是 php 一樣放上去就跑了,不過時代終於改變了,Mod_rails 出現了,他的名字叫做 Passenger

他做的事情就是讓設定Ruby on Rails 簡單到極點,省去所有設定繁複的設定手續,一個 Apache 就可以跑 Ruby on Rails。讓所有覺得 Ruby on Rails 設定困難的人全部閉嘴。 此東西一出,各方高手可都是讚譽有加

DHH : This could definitely become very popular, very fast ;)

Matz:It is often said that Rails is weak on deployment; PHP runs fairly fast just by uploading scripts. Rails is slow on development mode, and requires restarting on production mode (and bit complex to configure). modrails might be the answer for it.

效能
第一個問題是他的效能跟穩定性,跟現在市面上的 solution 有沒有得比。

根據他們自己的測試,看來是有大於 Mongrel,略贏過於 Thin 的效能。 Robustness 測試他們宣稱跟 Mongrel 一樣穩定,勝過 thin 還有 ebb。

安裝方式
既然是走簡單取向的 Apache ,那安裝方式當然要簡單點摟。只要你的 Server 上面有 Ruby / Rails / Gems / Apache2 ,那麼安裝方式就是兩下
1. gem i passenger
2. passenger-install-apache2-module

設定方式
既然是走簡單取向,設定方式要更簡單,你必須在 Apache 的 httpd.conf 裡面設定

LoadModule passenger_module passenger_module的預設目錄
RailsSpawnServer SpawnServer路徑
RailsRuby ruby路徑

別擔心找不到相關路徑,
screen-capture.png
上面的圖,我們可以看到在 passenger-install-apache2-module 過程中他會自動產生相關設定檔,給你貼上去。

剛剛是把 Rails 環境設定好,現在就是就是設定 DocumentRoot,

<VirtualHost *:80>
ServerName www.yourhost.com
DocumentRoot /rails目錄/public
</VirtualHost>

簡單講就是要設定清楚 Document Root,設定到Rails 目錄底下的 public 資料夾。,當然他也有範例 config 檔自動生成 XD
screen-capture-1.png


讓 Rails 跑在子目錄下
還沒測試,不過在 Doc 裡面有,看來可以很簡單的跑 PHP 跟 Rails 在同一個 Apache 下面(Bravo!!!)。

原理
採用類似 Apache mod_fastcgi 的方式,以一個 Passenger Process 來管理所需的 Rails process 量,隨著量的大小而動態增減 Process 數目。

結論
目前沒有明顯的結論,說 Passenger 一定勝過 Mongrel 或是 Lighttpd+fcgi 的 Solution。不過,看到他簡單的設定檔,還有看似不錯的效能跟穩定度,真的很值得期待。

4/08/2008

解決 Textmate 中文問題

沒想到我也會寫這種教學,不過既然有人問就順便講一下啦。嚴格說起來,我完全是參照這篇網頁所教學的方式。

Textmate 對中文的實在爛到不知道怎麼說,主要有兩個問題
1. 沒有中文字型
2. 不能顯示出輸入法提示列

要解決沒有中文字型的方式就是安裝中文字即可,請下載 TextMateJ2 這個字型。複製到 /System/Library/Fonts/ 底下,並且雙擊安裝。安裝字型之後,就是要選擇這個字型,請到 TextMate 的 Preference -> Fonts and Colors 最下面的字型裡面選擇 TextMateJ2。

screen-capture.png


要解決不能顯示輸入法提示列就是安裝 CJK-Input.tmplugin 。解開後就直接點 CJK-Input.tmplugin,他好像就會直接安裝了。

成品就是如底下圖。字型會擠擠的,這是沒辦法的事情。唯一解決方案就是等 TextMate 2 出。
screen-capture-1.png


JRuby 1.1 Release

JRuby 1.1 已經 Release 了,1.0到1.1最主要的不同是在「效能」的成長。JRuby 1.1 在很多 Benchmark 已經超越了 Ruby 1.8,甚至有些也贏過了Ruby 1.9。主要的修改有

1. Ruby code 可以 compile 成 Java Bytecode
2. Regular expression engine 改成 Oniguruma
3. 效能的進步以及相容性的進步

Ruby compile 成 Java Bytecode 一共有兩種模式(AOT或是JIT mode)。

JIT Mode 是預設,代表他會經過一段時間才會運轉到 compile Mode , JRuby Wiki 建議是 跑20次就自動到 JIT Mode 去。

AOT Mode 可以將 Ruby code compile 成 Java 的 .class 檔案。如果想要直接用 Java 去執行,要裝 JRuby.jar ,還有 asm-3.0.jar ,jna.jar。

下載連結:http://dist.codehaus.org/jruby/jruby-bin-1.1.zip

4/04/2008

更換主力 Editor ,改成 TextMate

這是一個困難的決定,不過是一個對的決定。

當我被某人勸說,不小心 Download 下來 TextMate 試用,彷彿打開所謂的禁忌之門,不久我就淪陷啦。我已經正式切換到 TextMate 上面了,vim 已經被冷落一週以上了。

你問我 textmate 好在哪裡,我只能說調性很合我的感覺。

是的,他有一卡車的缺點。這是我第一個花錢買的 Editor,第一個遇到居然連 Big5 都不能編輯的 Editor(他只接受 Unicode),也就是我要用 Vim 繼續處理 Big5 的 Project @@!。第一個連打中文字都要 Plugin 的軟體。

不過,該怎麼說呢。

Vim 是初戀情人,我用他用了5年,他對我有滿滿的回憶。Textmate 就是有很多缺點,但是卻愛的死心塌地,愛的轟轟烈烈的愛人吧。

如果這就是愛
在轉身就該勇敢留下來
就算受傷 就算流淚
都是生命裡溫柔灌溉~~~ 出自『如果愛」這首歌

Rack - 小架子立大功

最近 Ruby Web Framework 界出現了很多新面孔:
Ramze, Sinatra,Waves, Halcyon ,還有 4/1 才發佈的下一代 framework ==> Ruby on Crack!!

這些 framework 各有各的特點,除了為原本被 Rails 一統天下的 web 開發增添了新的風貌,也說明了 Ruby 社群的活躍。而他們(除了太神奇的 Crack 之外)的背後的大功臣,就是今天的主題: Rack

Rack 到底是何方神聖呢?


每個 web framework 最後一定要接回去 web server 。方法有很多,有人喜歡老牌的 Fastcgi ,有人愛用雜種狗,有人要像 mac book air 一樣,有人說退潮最快。

新的 framework 一直冒,新的 web server 一直來,每個人都要重新寫把兩者接起來的 code 實在太累了, Rack 就是為了解決這個問題而出現的。(1)

Rack

Web 程式講白了很簡單,就是拿 request 然後回 response。Rack 就是把各種 web server 的 request 和各種 framewrok 的 response 用統一的介面來處理。那麼這個統一的介面是什麼呢?

一句話

lambda { |env| [200, {}, 'Hello World!' }

首先, Rack 會將 request 傳給要處理這個 request 的物件的 call 函式。這個例子中,處理 request 的物件就是 lambda。(當然你可以用一般的物件,只要它有 call 這個 method 就行了。)
例子中的 env 就是 request,它是一個 hash ,裡面包含了類似 CGI Environment 變數,像是 PATH_INFO,QUERY_STRING 等等的東西。

而 call 的回傳值,會被當成 response 傳回去給 web server。這個回傳值必需是包含三個元素的 Array: status, headers 和 body。

原本 N 個 framework 和 M 個 web server ,要寫出 NxM 個 Adapter。而有了 Rack 後,大家只要對 Rack 的介面做 Adapter ,複雜度馬上減少為 N+M 了!

如此一來,不用一直重新實做橋接的邏輯,可以把心思放在 framework 本身的設計上。有了 rack ,相信 ruby 的 web 開發會更為有趣。

下一篇再來實際寫些 code 吧。


這張圖的 idea 是從這裡來的...

4/01/2008

[連結文] 為何有些 Java EE/J2EE 的專案是沒效率的,至少是效率低下的

原文連結在此,要看簡體翻譯在此。光是第一句我就笑死了。

我想到一句話,「教授是將簡單的事情變得很複雜,天才是把複雜的事情變得很簡單」。




3/31/2008

Rails 2.0 使用 Big5 編碼

沒想到我的有生之年居然還會使用到 Big5!!!

沒錯,基於機緣巧合,我碰到了一個需要使用 Big5 資料庫,網頁也是 Big5 顯示的request。所以我必須匿天而行,強迫 Rails 2.0 使用 Big5。方法很簡單,

config/enviroment.rb 裡面加入
config.action_controller.default_charset = "Big5"

config/database.yml記得加入
development:
host: xxx
adapter: mysql
database: lala
port: 3306
username: root
password:
encoding: Big5

Html 記得加入
<meta http-equiv="content-type" content="text/html;charset=Big5" />

大概就這樣吧,我抱著參觀懷舊的心情來寫這個網頁 XD

3/20/2008

Rails 2.0 比起 Rails 1.2 加速不少

好像是一個對岸人赖洪礼 在自己 blog 發表一篇壓力測試。他發現到 Rails 2.0 比起 Rails 1.2 加速不少,大概是 30%~50%。不過,他的測試方式相當的原始,用 ab 去量 scaffold 頁面的 req/sec。所以數字比例根本不能做准。

但是,至少說明 Rails Team 有在為了 performance 盡力,並且有實際的成果。

3/15/2008

Netbeans 6 相當的威

前陣子需要一個 IDE 來教課,需求如下



  1. 好安裝


  2. 跟 Rails 整合良好


就選了 Netbeans 6 來試試看,結果發現真的還蠻不錯的,因為都是 Sun 的東西,所以直接跟 jruby 有很好的整合



  • Navigation 還不錯用,可以直接跑到這個 Controller 相關的 View,或是這個 View 相關的 Controller ,也可以指到這個 Class 宣告的地方。


  • 內建 svn ,也比 Eclipse 還得裝 SubEclipse 來的方便。


  • 內建 jruby ,也可以直接包成 war file


  • Find Usage 可以找出所有使用這個 class 的程式碼所在,主要找出所有使用這個 Model 的 Controller 列表


  • 內建 mysql GUI Tool


  • Code Hint 超棒


最重要的是,他可以直接把 Model 對應到 attribute 給取出來


activerecord6.png


Product Model 裡面有 description,image_url ... title 等 table column ,Netbeans 6 可以直接取出來放到 code hint 裡面去。這樣就省了點找 db column 的時間了。不過這個功能必須使用 migration ,或是將 db schema dump 到 schema.rb 才可以用,也就是說不是 live db connection 去取 schema 啦。


Netbeans 6 最大的缺點就是速度太慢了.......,不過 6.1 Beta 已經改善了不少。大家可以試試看。


不過我的話,還是 vim 無敵呀。Navigation 用 gf 可以直接跳來跳去,Find Usage 可以用 grep -r --color Patern dir 來取代, 取出 db schema 可以直接用 mysql client + explain db schema 來做到。鍵盤還是真正的王道。




3/09/2008

Rails PUSH Server :Juggernaut 簡介

早就想寫 Juggernaut 的文章了,不過今天是第一次有時間寫。Push Server 技術就不再提了,想知道可以看我之前寫的文章。

簡介

Juggernaut 簡單的來說,是一個 Ruby Push Server 加上 Rails Plugin。

Push Server 取名就叫作 Juggernaut。

Juggernaut 的 Rails Plugin 裡面包含了一些 JS,跟Juggernaut 自己開發的 Flash Client。Push Server Client 端通常需要 Flash 來接收 Push Server Message,Juggernaut Flash Client 是使用 Flash 8 來作開發。支援 IE ,Firefox,Safari。Juggernaut 的強項在於跟 Ruby on Rails 整合良好,我們來看看怎麼使用。

安裝

1. Push Server 安裝

gem i juggernaut -y

2. Rails Plugin 安裝

ruby script/plugin install http://juggernaut.rubyforge.org/svn/trunk/juggernaut


設定

1. Juggernaut_hosts.yml

這裡很容易混淆,這個設定檔是 Rails Plugin 要看的設定檔,如果沒有設定 config/juggernaut_hosts.yml,會導致 Rails 無法啟動,所以必須要設定 config/juggernaut_hosts.yml。請先新增一個 config/juggernaut_hosts.yml ,輸入你的 Push Server 環境

:hosts:
- :port: 5001
:host: localhost
:environment: :production

port 是 push server port ,預設是 5001,Host 是 Push Server 的 IP ,Enviroment 是 Rails 環境。

2. juggernaut.yml

我們用 juggernaut 來產生 juggernaut push server 所需的設定檔。以下指令會產生一個 juggernaut config 檔,取名叫作 juggernaut.yml。

juggernaut -g juggernaut.yml

啟動

要啟動就是要啟動 Push Server ,還有 Ruby on Rails 。
1. 啟動 push server
我們啟動 juggernaut 這個 push server,並且讀取 config 檔。 預設 Push Server port 是 5001,可以到 juggernaut.yml 去修改。
juggernaut -c juggernaut.yml

範例

我們直接用 juggernaut 的範例,聊天室來確認是否 ok。在你的 controller 裡面創立兩個 function
def index

end

def send_data
render :juggernaut do |page|
page.insert_html :top, 'chat_data', "
  • #{h params[:chat_input]}
  • "

    end
    render :nothing => true
    end
    然後在 index view 裡面這樣寫
    <html>
    
    <head>
    <%= javascript_include_tag :defaults, :juggernaut %>
    <%=
    juggernaut %>
    head>
    <body>
    <%= form_remote_tag( :url => { :action => :send_data }, :complete => "$('chat_input').value = ''" ) %>
    <%= text_field_tag( 'chat_input', '', { :size => 20, :id => 'chat_input'} ) %>
    <%= submit_tag "Add" %>
    < /form>
    < id=""chat_data" style="list-style:none"> ul>
    body>
    html>
    這樣聊天室就完成啦,可以試試看玩玩看。

    對了,這個聊天室一開始有一堆 alert message,這是 Juggernaut 預設 Development 環境下會啟動 Debug Function ,只要 config 改成 Production 就不會出現一堆 alert message。

    3/05/2008

    Ebb:又來一個的 Application Server

    這年頭發展 Application Server 好像很有搞頭,也或許是 Rails 社群對 Zed Shaw 的高調離去的反撲。總之,2008 年一月出了 Thin,二月出了SwitchPipeSwiftiply,現在又有一個 Rails App Server Ebb 出了,而且好像真的很有料。




    ebb-concurrency.jpg


    上面這張圖是 ebb 跟 Mongrel ,和 Event-Driven Mongrel,Thin 的負載程度 benckmark。我們可以發現 ebb 跟其他的 Rails App Server 根本就是不同等級的負載程度。他的 Design 架構上面比較像 Event-Driven Mongrel,差別比較大的就是他很多地方用 c 寫成。


    安裝方式


    gem i ebb


    記得先安裝 glib2。


    跑的方式


    ebb_rails start


    很熟悉的指令。


    測試一下好了。




    2/28/2008

    Friends for Sale :一天一千萬 Page View 的 Rails Service

    app_3_7019261521_7189.gif



    Friends for Sale 是一個在 FaceBook 上面排行前十的 Facebook App,最近他公佈他的資料,他是 Ruby on Rails 寫的。他上面有 60萬個會員,一個月 3億個 PV,並且以每個月 300%繼續成長。上個月流量是 3T,不過大部份都是圖片的支出。



    架構是標準的 Rails Cluster,Front end 是 Nginx,Application Server 是 Mongrel。



    他們學到課程如下



    1. 如果在Facebook 上面開發 APP,一開始就要想到 Scaling Problem(四周就衝到 1 m pv/day)


    2. Ruby on Rails can scale


    3. Performance Problem 是在 DB,你需要有很好的 DBA


    4. Cache 用的好,DB 不嫌少


    他們使用



    1. Ruby on Rails


    2. CentOS 5


    3. Memcached


    4. MySQL 5.1


    5. Nginx


    6. Starling( Distribute Queue Server)


    7. Dr. Nics Magic Multi-Connections Gem ( Read Write 不同個 DB)


    使用硬體



    1. 6台 4 core 的 App Server,每台 16 Mongrel Instance,並且每台都放 4GB Memcached 。


    2. 4台 DB Server,上面配備 32GB 4 core servers with 4x 15K SCSI RAID 10 disks,使用 Master-Slave,用 Multi-Connection Gem 來達成 Read Write 不同 DB。


    3. 1 Starling Server


    4. 1 frontend server









    Adobe 計畫擴展Flash 支援其他語言

    JavaEye 看到的東西Adobe CTO Kevin Lynch在 Adobe Engage 上面講說,他們預計將其他 language 帶入 Flash ,使得 Flash 不只是可以用 ActionScript,還可以使用其他的 Language。最後也只是將 Language Compile成 Flash 的 swf Bytecode。


    感覺又是一個 VM 的即將誕生。




    2/19/2008

    Rice - Ruby Interface for C++ Extensions

    Rice - Ruby Interface for C++ Extensions

    一年半前(天啊,有這麼早嗎?)曾經介紹過 swig, 一個專門產生各種介於 C/C++ 與其他語言 interface 的產生器。他是利用一個自訂的表示法,藉由讀取該表示法,產生出各種不同真正的 binding 程式。其中也有內建不少 STL 的 binding,所以想用 STL 的東西並不見得需要自己寫,只要叫他內部的東西出來即可。

    swig 很厲害,不過他有個麻煩。雖然說 DSL 的威力強大,但是對於想要快速上手而言,其實有時候反而會是種阻礙。另一方面,我 swig 手冊翻了翻,要把 C++ port 到 ruby 很容易,但反之不亦然,要在 C++ 中使用 ruby object, 就不是那麼方便。(雖然也許這樣做是奇怪了點...)

    所以後來我試了 Rice.
    http://rice.rubyforge.org/
    rice 的官方手冊也說了,rice 並不是要來取代 swig 的。swig 有他的不足,而 rice 大抵上又是模仿 boost.python 而作成的,所以兩者並不同。他自己也做過不少東西是同時使用 swig 和 rice. 不過也不能說 rice 是 ruby 版的 boost.python. 因為他的目的也不是完全模仿 boost.python.

    anyway, 之所以會想試用,是出自於找不太到良好的 C++ yaml parser. 我有看到兩個 C 版本的實作,但是真不好意思啊,個人實在不太喜歡純 C 的東西...。所以想說如果可以把 ruby 的 yaml 搬過來就太好了。以下就是測試結果:

    > sudo gem install rice

    理論上這樣安裝是最方便的。要在 C++ 裡執行 ruby, 一樣會需要 ruby.h. 一般來說,他會在 lib/ruby/1.8/your_architecture/ 裡面。在我的電腦上,他是:/opt/local/lib/ruby/1.8/i686-darwin9.1.0/

    而 rice 呢,則是在 lib/ruby/gems/1.8/gems/rice-x.y.z/, librice.a 則是在 lib/ruby/gems/1.8/gems/rice-x.y.z/rice/ 下。

    所以在我的電腦裡,g++ options 是這樣下:

    -I/opt/local/lib/ruby/1.8/i686-darwin9.1.0/ -I/opt/local/lib/ruby/gems/1.8/gems/rice-1.0.1/ -L/opt/local/lib/ruby/gems/1.8/gems/rice-1.0.1/rice/ -lrice -lruby -std=c++98 -Wall -w

    主程式大概是長這樣:

    int main(){
    using Rice::Hash;
    using Rice::protect;

    ruby_init(); // 使用 ruby 前一定要呼叫
    // 設定 load path, 否則 load path 會是 []
    rb_eval_string("$LOAD_PATH << '/opt/local/lib/ruby/1.8'");
    rb_eval_string("$LOAD_PATH << '/opt/local/lib/ruby/1.8/i686-darwin9.1.0'");

    // require yaml 進來。當然也可以用上面的方式 require. 不過之所以會這樣寫,
    // 是因為我不知道 load path 要怎麼直接從 rb_ function 中設定?
    // 否則我是覺得能用 rb_ 去跑盡量用,evil eval 不是叫假的...
    rb_require("yaml");

    // protect 我猜是把所有的錯誤都轉成 rice 本身的 exception.
    // Hash, 則是 ruby 的 hash 在 C++ 裡的 wrapper,
    // 所以我是把 YAML 的讀取結果存入這份 C++ Hash 中。
    Hash h(protect(rb_eval_string, "YAML.load(File.read('database.yml'))"));

    // 這邊,我要做的事只是展現如何使用這份 hash.
    Extractor e;
    e.extract(h);
    std::cout << std::endl;
    }


    雖然我覺得 doxygen 生出來的東西常常很難閱讀,不過 rice 的 doxygen 文件還算不錯,有什麼東西都很清楚。就算不夠清楚,也能去直接看他的原始檔。他原始檔的東西並不多,稍微翻一下,有什麼疑惑我想都可以解決。根據我 C++ 的經驗,rice 這份程式也算是寫得非常漂亮的了,應該滿有參考價值。

    我的 extractor 是把整個 hash 都走過一次,如果不需要這麼複雜的操作,其實也可以很單純地這樣呼叫:

    std::cout << static_cast<Hash>(h[String("development")])[String("adapter")];

    這樣會輸出:

    sqlite1

    這樣實在是有點囉唆沒錯,不過我想這可以靠擴充 rice 解決。他有個 from_ruby 和 to_ruby 的 template, 擴充那個東西,好像就能把很多東西從 explicit 法轉成 implicit 法。不過我暫時懶得去做那麼多研究,這應該都是小問題。不過 down cast 就比較麻煩了。他有個 get method, 好像是能做一些 down cast, 但我測試都會有 runtime error, 大概是用法不對吧。有興趣的人歡迎去研究看看要怎麼做。

    extractor 我想就不解釋了,就只是單純把抓出的 yaml 再輸出回 yaml. 其實那都已經差不多單純是 C++ 的問題了。僅列出程式碼與附註的一些註解:(不過我沒測試過比較複雜的 yaml, 我想一定會有問題,當作業自己試著改好吧 :p)

    #include <ruby.h>
    #include <rice/Hash.hpp>
    #include <rice/Array.hpp>
    #include <iostream>

    using Rice::Object;
    using Rice::Class;
    using Rice::Hash;
    using Rice::Array;
    using Rice::String;

    // 排版算空格用的
    std::string spacer(int depth){
    std::string result;
    for(int i=0; i<depth; ++i)
    result += " ";
    return result;
    }

    class Extractor{
    public:
    // 他 class 判斷法有點麻煩,所以我先把這三個 class instance cache 起來
    Extractor(): hash_class_(Hash().class_of()),
    array_class_(Array().class_of()),
    string_class_(String().class_of())
    {}
    void extract(Object const& obj, int depth = 0) const{
    if(obj.is_instance_of(hash_class_))
    extract_hash(obj, depth);
    else if(obj.is_instance_of(array_class_))
    extract_array(obj, depth);
    else if(obj.is_instance_of(string_class_))
    std::cout << spacer(depth) << obj << "\n";
    else // 這表示他是 Fixnum or Float?
    std::cout << spacer(depth) << obj << "\n";
    }
    private:
    void extract_array(Array const& obj, int depth) const{
    for(Array::const_iterator i=obj.begin(), iend=obj.end(); i!=iend; ++i)
    extract(*i, depth);
    }
    void extract_hash(Hash const& obj, int depth) const{
    for(Hash::const_iterator i=obj.begin(), iend=obj.end(); i!=iend; ++i){
    std::cout << spacer(depth) << i->key << ":";

    // i->value 結果會是 ruby 上 C 的 VALUE, 所以要 cast 成 Rice::Object
    if(static_cast<Object>(i->value).is_instance_of(hash_class_))
    std::cout << "\n", extract(i->value, depth+1);
    else // 單純的值
    std::cout << " ", extract(i->value, 0);
    }
    }
    private:
    Class hash_class_, array_class_, string_class_;
    };

    2/03/2008

    Twitter 正式離開 Joyent

    大神那看到的消息。Twitter 之前選擇 Joyent 作為自己的 Hosting Service ,不過為了提供更穩定的服務,他們決定移轉到 NTT American 這家公司。

    1/22/2008

    微軟即將把IE6強制升級至 IE7

    大神那看到的,微軟將作一件功德無量的好事,他們即將在今年二月十二號,利用 Windwos Server Update Service 將系統裡面的 IE6 改成 IE7。

    相信此一升級對於 IE6 only 網站來說是一個大震撼,恐怕也會有大幅度的網頁改版潮。但是對於任何一個網頁程式設計師,或是網頁美工來說,都是一個放鞭炮的消息。

    1/17/2008

    Thin :有可能超越 Mongrel 的 App Server

    介紹

    在Zed Shaw 離開了 Mongrel 之後,每個使用者人心惶惶,不知道 Rails 的 App Server 會不會出大問題。這時候,彷彿在跟 Zed 說「Rails 社群不會被打敗」,Thin 出現了。

    Thin 是一個 Mashup App Server ,採用了作者認為 Ruby 當中數一數二好的 Lib
    • Mongrel Parser:Mongrel 速度跟安全性的根本
    • Events Machine:快速,穩定的 Network IO Lib
    • Rack:Webserver 跟 Ruby 之間的 Interface
    這幾個強大的 Lib,整合在一起分工合作,讓 Thin 成為安全,穩定,快速,好擴充的 Web Server。

    當然,快速是他第一個優點。在他的測試中, Thin 超越了 Mongrel 跟 Event-Driven Mongrel。
    JavaEye 網友的測試也發現,不論是 Ruby 1.8 ,Ruby 1.9,Thin 的速度也是超越 Mongrel 。Ruby 1.9 裡面 req/s 居然是 4154 : 1313 的可怕差距
    Mongrel 1000 100 1313.19 0
    Thin 1000 100 4154.67 0

    安裝方式

    用 gem 安裝即可
    gem i thin
    要執行 thin ,就是在 Rails 的根目錄下執行
    thin start
    可惜沒有 Cluster 版本,不過,對岸網友已經寫了一個應急的 rake file,只可惜沒有指定 Port 的 command,所以我稍微修改一下成為這樣
    namespace :thin do

    namespace :cluster do

    desc 'Start thin cluster'
    task :start => :environment do
    `cd #{RAILS_ROOT}`
    (ENV['SIZE'] ? ENV['SIZE'].to_i : 4).times do |i|
    Thread.new do
    port = ENV['PORT'].to_i + 1
    str = "thin start -d -p#{port} -Ptmp/pids/thin-#{port}.pid"
    str += " -e#{RAILS_ENV}"
    puts "Starting server on port #{port}..."
    `#{str}`
    end
    end
    end

    desc 'Stop thin cluster'
    task :stop => :environment do
    `cd #{RAILS_ROOT}`
    Dir.new("#{RAILS_ROOT}/tmp/pids").each do |file|
    Thread.new do
    if file.starts_with?("thin-#{port_range}")
    str = "thin stop -Ptmp/pids/#{file}"
    puts "Stopping server on port #{file[/\d+/]}..."
    `#{str}`
    end
    end
    end
    end

    end
    end
    將這個東西貼在 Rails 根目錄的 Rakefile ,將它貼在最後面,然後執行下面指令啟動
    rake thin:cluster:start RAILS_ENV=production SIZE=10 PORT=4000
    灰色的代表可以自己填寫的選項,包含 Rails 啟動的 enviroment,執行幾個 thin ,還有從哪個 Port 開始 listen。有用過 mongrel_cluster 應該都很清楚。停止就是
    rake thin:cluster:stop
    他會砍掉 tmp/pids/thin- 開頭的 pid file。

    Sun 買下 MySQL

    今早看到的新聞,還蠻震撼的,Sun 買下 MySQL。此舉讓 Sun 成為 Open Source 廠商中數一數二的領導地位。BTW,nobody knows it will be good or bad.

    SANTA CLARA, CA January 16, 2008 Sun Microsystems, Inc. (NASDAQ: JAVA) today announced it has entered into a definitive agreement to acquire MySQL AB, an open source icon and developer of one of the world's fastest growing open source databases for approximately $1 billion in total consideration. The acquisition accelerates Sun's position in enterprise IT to now include the $15 billion database market. Today's announcement reaffirms Sun's position as the leading provider of platforms for the Web economy and its role as the largest commercial open source contributor.

    1/10/2008

    JRuby 1.1 RC1 Release

    本文

    JRuby 1.1 RC1 Release!!!
    正如之前所看到的消息,JRuby 1.1 跟 JRuby 1.0 最大的改進就是在 Performance 的不同,速度上比起 1.0.2 約有 27% 的改善,主要的改進有兩個

    1. JRuby 可以用 Ahead Of Time (AOT) 或是 Just In Time (JIT) 兩種模式進行 compile。
    2. JRuby 使用 Oniguruma 的 JRuby porting Juni,當作 Regular Expression 的 Engine。

    總之,恭喜 JRuby Team。

    下載:http://dist.codehaus.org/jruby/



    本文結束後的講古,爆米花請準備好

    說到 JRuby 的 regular expression ,可有說不完的故事(可以看 InfoQ版本)。

    早期 JRuby 原本使用 Java 1.4 以後內建的 regex ,雖然很簡單,但是以一個目標是 Ruby 1.8 compatiable 的 project 來說,Java 內建的 regex 不合用。為了解決這個問題, JRuby Team 改採用 JRegex ,並且也納入了 JRuby 1.0 裡面。

    但是 JRegex 某些細節跟 Ruby Regex 不太類似,依舊傷害了JRuby 對於 MRI Ruby 的兼容性 ,而且 JRegex 以 Java 的程式來說,已經算很快了,但是依舊不夠快速。 JRuby Team 在測試JRuby 跑 Rails 的時候,他們發現 regular expression 成為顯著的 Bottleneck。
    And I found that there was one in particular that had really interesting performance when comparing MRI to JRuby. In fact, it was between 200 and a 1000 times slower. What's worse, the performance wasn't linear.
    所以他們決定使用更快的 Regular Expression Engine 來徹底解決 JRuby on Rails 的效能問題。他們選中了 Oniguruma 這個 Ruby 的 regular expression Engine,這是 Ruby 1.9 內建的新 Regular Expression Engine。

    Oniguruma 看來難念,其實是日本字,意思是鬼車,不過比起鬼車,我比較喜歡對岸的講法 XD
    O ni guru ma
    哦 , 你 咕噜 吗?
    真的好記很多。Oniguruma 支援多個 charset 的 regular expression,已經是一個成熟的 regular expression engine。所以 JRuby Team 選擇了 Oniguruma 當作新的目標,將他 Porting 成 JRuby 版本,並且將他改名為 Juni。後來發現 Juni 相對於 JRegex ,的確對於 JRuby 帶來了顯著的效能上升

    1/08/2008

    Ruby 跟 Python 本質上不同

    前言

    對岸高手孟岩最近寫了一篇「Ruby 1.9不会杀死Python」,裡面提到 Ruby 1.9 一出,彷彿 Ruby 已經邁向完全體,所有的缺點都已經消失了。彷彿已經要一統武林
    有人认为,这下子不得了了,Ruby要称霸动态语言了。你想想,Ruby已经几乎拥有了所有梦幻般的语言特性,神奇的动态能力,强大的支持库,内置的跟Perl可以比肩的正则表达式,Smalltalk级别的纯而又纯的面向对象特征,简洁明快的风格,跨语言整合也非常容易,唯一的缺点就是速度慢。现在连这个缺点都被弥补了,Ruby还能挡得住吗?其他的动态语言都该歇菜了。
    然後他又提到一個很有趣的分類,Ruby 是魔幻語言,Python 是簡約語言。Robbin 老大也出來講了Ruby为什么会受程序员的欢迎?。一整篇看下來,實在是很過癮。

    簡約語言

    簡約語言是什麼呢?大致上是 C、PHP、Python和Lua,C# ,Java。他的大概意含可以由Python 的中心思想 EIBTI 可以略知一二
    Explicit is better than implicit.
    看不懂的話,用更白話的方式來解釋,The Zen of Python 裡面有提到
    There should be one-- and preferably only one --obvious way to do it.
    也就是,Python 有意的限制語言的表示方式,使得不好的 coding 習慣都不能 Compile 過,有意的強制使用者養成良好的習慣。

    這雖然極端了點,但也不超乎其他簡約語言的中心思想。簡約語言不關心語言的表述方式,他們在乎的是「解決問題」。以工程來看,簡約語言在大專案裡面的協同工作上面較為吃香。

    魔幻語言

    我很喜歡這個詞。魔幻語言的代表有 C++、Perl、Javascript和Ruby。中心思想可以由 Perl 的 TMTOWTDI 來表示
    There's More Than One Way To Do It.
    魔幻語言的擁護者思考的東西,這位孟岩老大也描寫的很傳神
    他们写的代码是一种谜语般的艺术,出谜语和猜谜语的人们都能从中获得巨大的精神满足
    但是,請不要輕易的把 Ruby 歸於「華而不實」這一派。Robbin 老大也在這裡講到
    C++的魔幻语法会导致代码的可读性变差,而Ruby的魔幻语法会导致代码的可读性大大提高。

    不论是matz本人,还是整个Ruby社区,Rails社区诸多开源项目的作者,抑或整个Ruby和Rails开发者社区,在一个编程哲学问题上是高度统一的,这就是:

    强调程序员的快乐编程,追求人性化编程,在代码的可读性上面有偏执的追求,拒绝难以阅读的代码和难用的API。也就是所谓的coding for fun!
    Ruby 奇妙的手法,以及 DSL 的技巧,都是為了達到跟 Python 同樣的 Promise Land ,那就是「code 可讀性」。只是兩者作法不同而已。

    兩者的不同

    兩者最大的不同是在「開發者的審美觀以及開發風格」上。不是語言的不同,是使用者個性上的不同。
    回到开头的话题,Ruby是一个典型的魔幻语言,而Python则是简约派的代表。两个语言的支持人群在审美观念和开发风格方面差距非常大。初学Ruby和Python的人,都会感受到一种欣喜和兴奋,但是原因却不太一样。Ruby的学习者会惊喜于很多新的表达方式,比如 :attr_accessor 之类的魔幻特性,而Python学习者则会惊喜于实现具体功能的简洁性。可以说从一开始他们追求的就是不同的东西。随着学习的深入,Python开发者当然也会发现Python中的不少深入的特性,不过却并不倾向于滥用它们。长次以往,Python人群对任何语言的魔幻面都会产生一种厌恶感。我认识的一个Django开发者,就明确表示,就算RoR比Django开发效率高一点,也绝不使用Ruby,因为Ruby这个语言充满了“不必要的小聪明”。
    高手果然是高手,好露骨的講法。Python 人對於「語言的魔幻面」,或是你要稱為「奇技淫巧」有種本質上的厭惡感,很多 Ruby 人引以為傲的東西,都會被視為「惡魔」。儘管 Python 也可以玩出些好玩的把戲,但是他們的中心思想讓他們「選擇不去作」。

    而 Ruby 正如上面所說得,Ruby 人會被鼓勵使用「語言的魔幻面」,並且從中獲得相當的精神上的樂趣。但是跟「華而不實」最大的不同,是在於 Ruby 是利用語言的炫技,達到超乎想像的開發效率跟可讀性。最後,偉大的傑作誕生了,Ruby on Rails 用本身的「魔幻面」,反而達成了比PHP 這種 Web 專用的簡約語言的更高的可讀性。

    本質上的不同?還是人的不同?

    人的 tone 不同,才是真正的問題所在。或許雙子座的我,永遠不會欣賞 Python :p

    奇想

    不知道為什麼,寫這篇文章的時候,總是把魔幻語言想成魔法師,簡約語言想成戰士。所以腦中一直圍繞著 Ruby 是魔法技能點數 10 的魔法師,前面還有一個血防加到滿的戰士在前面罩著(Java),然後組隊一起打怪。

    恭喜 Python 成為 programming language of 2007

    TIOBE 原文翻譯文在此。值得稱讚的是,Python 首度超越 Perl 。

    這年頭 Scripting Language 當道,Ruby 是2006 年的年度語言,Python 成 2007年的年度語言。明年 Ruby 再把這個殊榮拿回來吧 :p

    1/07/2008

    ludy 0.0.9 released

    其實後來的更新幾乎都是亂寫了,這次的更新也差不了太多。大抵上就是增加個 C++ TR1 style 的 bind... 用起來的味道大概是這樣:(如果熟 C++ TR1/boost bind 的話,一眼就知道了)

    assert_equal [9,8,7], ([1,2,3].map &(lambda{|lhs, rhs| lhs-rhs}.bind 10, :_1))
    assert_equal [3,2,1], (lambda{|a,b,c| [a,b,c]}.bind :_3, :_2, :_1)[1,2,3]
    assert_equal [1,9,3], (lambda{|a,b,c| [a,b,c]}.bind :_1, 9, :_3)[1,2,3]
    assert_equal [9,2,3], (lambda{|a,b,c| [a,b,c]}.bind 9)[2,3]
    assert_equal [9,4,2], (lambda{|a,b,c| [a,b,c]}.bind 9, :_3)[2,3,4]

    不過我總覺得 ludy 應該可以繼續走下去才對。所以我想在下次做一次 major update, 版本號大概就是 0.1.0 吧。會做的改變大概如下:

    1. 整理 project directory structure, 現在根本就是亂七八糟。我想大概會用 gem bones 去做吧。其實我是比較 prefer hoe, 但是 bones 的 rake task 有 namespace 比較漂亮... 如果 hoe 會更新到使用 namespace 的話,我再 switch 過去。現階段,我想 bones 是個不錯的選擇。

    使用這種東西的好處,當然就是不用去設計 directory structure... 而且自己寫 gemspec 老實說也真的是滿麻煩的,bones 和 hoe 都有 rake task 幫我 build gem 檔,甚至還有 publish, 多方便。

    2. 思索 puzzle_generator 的未來。其實他跟 ludy 一點關係都沒有,只是我為了使用 svn server 所以才把他加到 ludy 上的。到底 puzzle_generator 應該分出來,還是在 ludy 中找到一個位子?分出來的話,又該分去哪裡?

    3. ruby 1.9 compatibility, 我剛剛稍微測試了一下,有幾個比較髒的東西在 ruby 1.9 是跑不起來的。這個應該要想辦法修掉,ruby 1.9 很棒的。除了效能好很多以外,多了很多我想要很久的功能,能早點轉過去就早點。可惜的是 1.9 問題還很多,而且很多 gem 沒辦法在上面跑,所以 1.8 還是必備的。現階段會讓 1.8 和 1.9 都相容,等 1.9 夠穩了,就不會考慮支援 1.8 了。

    4. require path 的麻煩問題。去看看 facets, 他們對於 require path 大概也很頭痛吧。從 2.0.0 就整個把 require path 翻修過,結果還有大 bug, 害我完全沒辦法用。果然很快就推出 2.0.1 了...。還是 2.0.1 ~ 2.0.2 的階段,我忘了。反正就是很可笑的狀況,名稱衝突之類的。bug 期間我是暫時 monkey patch.

    再看看 rubygems, 一開始有個 require_gem. 而我,卻也弄了個 require_ludy. 沒辦法,因為很難寫一個在任何情況下都有效的 require, 所以才搞出那種東西。但是現在我覺得,還是應該多為 user 想想,畢竟連 rubygems 都捨棄 require_gem, 我也不該繼續使用 require_ludy 才對。

    無奈這真的是個很大的問題,可能勢必得做得不要那麼 general 吧?大致問題如下:
    a. 使用 gem install 時可以正常 require.
    b. 把東西全部 copy 到 project path 時, 讓 -I 可以 work.

    其實簡單地說,就是希望不要 gem install 也可以輕鬆放到專案中使用。不過也許得放棄這個要求吧?因為實際在寫時,就會發現很多問題都跟這有關。如果能「假設」gem 一定有安裝起來的話,很多考量就可以不用做了。

    事實上,不需要安裝 gem 也能 work, 對於開發也很有用。因為我可以改改程式就測試最新的結果,而不必自己裝一份。所以,還是再看看吧。還是希望能有好方法。

    5. unit testing. 既然是 unit testing, 當然就要有能夠分開 test 的動作。我希望可以 ruby test/tc_bind.rb, 也可以 rake test 測試所有的 unit test. 之前因為沒在用 rake, 我自己寫了個 ts_ludy.rb, 大概就是做這件事。所以 ruby test/ts_ludy.rb 就可以跑所有的測試。

    而我發現,如果照 unit test 原先的設計,把所有東西都 require 起來再跑,執行效能會變得很爛很爛。原因我不是很清楚... 所以後來我改變作法,變成一個個去跑每個 unit test, 然後把輸出結果蒐集起來,再報告出去。這樣的好處就是跑得速度真的快太多了,好幾倍的差別。缺點當然就是,這樣做挺詭異的...

    所以關於 testing 的部份,也還需要再整理一下。大致就是希望能單獨跑也能一起跑。另一方面,我要求 testing 所使用的 lib 應該要是相對路徑下的,而不是 gem 上的。理由同 require path 上面的描述。

    其實對於 require path 和 unit testing 的部份,我花了不少功夫,不過成果其實還滿差的。當時看是沒什麼感覺,現在看覺得實在很醜。

    6. 去掉 shebang, 那很蠢。(那時候對 shell 太不熟了)

    7. ludy_ext.rb
    這東西,本來是想放各個沒在 Ludy module 下的東西,不過這樣成長太噁心了。應該學學 facets, 一個 method 一個檔才對。所以這部份也要切開,整理一下。

    8. 整合之前為了 shooting-cubes 做的一些 rake task, 還有 erb meta-programming 的一些相關 method. 這個,和 puzzle_generator 一樣好像有點尷尬,不太屬於 ludy 的範疇。
    不過在整個 ludy 東西還很少的狀況下,我希望盡量整合一些 lib.

    9. 儘快整合 multi, 那個 multi-method 的 lib. 我在想,我可能自己實作一份,就不要直接把他吃進來。multi 是 MIT license, 我想我直接吃進來應該沒問題,只是整個感覺就很怪,而且他的程式有些部份我不太滿意,所以也許我自己做一份還是比較好,這樣也不用想怎麼合併。

    如果確實做出來了,那大概就只留一份 NOTICE 或感謝之類的,就不保留原本的 require path 了。不然,我真的覺得那樣很醜,像是分裂的個體似的。

    10. 修改一些文字說明,包含 README, CHANGES, description 之類的。現在的格式已經有點接近亂寫了。另一方面,也希望稍微修改一下 rubyforge 上的 release 結構。

    11. 撰寫 rdoc, 完全沒 doc 其實也有點奇怪...

    *

    所有的 source code 都採用 Apache License 2.0, 希望下次的更新可以涵蓋以上幾點。

    btw, bind 實作只有 13 行(含註解)

    安裝:
    gem install ludy

    取得所有程式:
    svn checkout http://ludy.rubyforge.org/svn/
    or
    svk mirror http://ludy.rubyforge.org/svn/ //mirror/ludy

    1/04/2008

    Rails Is A Ghetto

    先說好,Mongrel 是一個 Team ,所以 Zed Shaw 的離開不代表 Mongrel 的停擺,不過該開始尋求更好的 Application Server 摟。

    Zed Shaw (Mongrel 的作者)在去年的 12/15號宣告他封鍵盤,不再 Coding 了。然後又在去年的最後一天發表了一篇攻擊性言論相當強的文章,Rails is a Ghetto。裡面提到許多 Rails 社群的不良行為,並且用相當攻擊性的語氣來批評這些行為。這對 Rails 社群的確有很大的傷害,不過有多大那很難說。

    Zed Shaw 宣佈他不是 Ruby Guy,並且想轉向 Python,Factor,Lua 等語言看看。
    "This is that rant. It is part of my grand exit strategy from the Ruby and Rails community. I don't want to be a 'Ruby guy' anymore, and will probably start getting into more Python, Factor, and Lua in the coming months. I've got about three or four more projects in the works that will use all of those and not much Ruby planned. This rant is full of stories about companies and people who've either pissed in my cheerios somehow or screwed over friends. I can back all of them up from emails, IRC chat logs, or with witnesses. Nothing in here is a lie unless it's really obviously a lie through exaggeration, and there's a lot of my opinion as well."
    大家想看去看原文吧 :) 。你不用去期待裡面有啥技術,Performance ,語言架構的比較。裡面只罵人跟公司(ThoughtWork)。我很不喜歡這篇文章,因為語氣不只是差,還有許多人身攻擊
    Dave Thomas Ain’t No Sammy Sosa (He’s Just Fat)
    之類的話語。更讓我覺得 Zed Shaw 的 EQ 似乎不是很好。

    不過,Zed Shaw 對於 Ruby on Rails 的社群貢獻是毋庸置疑的,至少讓我對你唱一句
    Goodbye My Love,我的愛人再見
    祝你在新的社群有好的發展,還有 Ruby 社群沒有加蓋,你在外面受到不好的遭遇可以游回來呀。

    1/01/2008

    用 Blogger 寫技術類型文章的優勢

    我當初選用 Blogger 寫 LightyROR 這個技術類型的 Blog ,就是看在

    1. 技術人員都用 Google
    2. Google 「應該」會對 Blogger 作技術文章搜尋結果作最佳化

    請注意,是應該,而不是肯定。我「猜」 Google 當然會對自家產品稍微愛護一下,而看我 Blog 的人應該都是用 Google ,所以我選擇 Blogger 。

    結果今天發生了一件事情,我四點寫了一篇 CentOS 5.1 + RMagick works,結果一個小時後我 Google 搜尋「CentOS RMagick」文章的時候,發現已經進入 Google Search資料庫,並且排名第二名

    雖然不能說 Google 有對 Blogger 的文章有特別愛護,但是寫完文章後,一個小時進入搜尋搜尋資料庫,也算是另類的優勢。

    CentOS 5.1 + RMagick works

    昨天,我要在 CentOS 上面灌 RMagick。我 google 了一下,發現有位卧得罚先生寫關於 CentOS 下面安裝 RMagick 的辛酸跟血淚,洋洋灑灑六到七頁,最後成功了還不忘加句「CentOS Sucks」。我發現到 XDite 也又 twitterCENTOS 裝 rmagick ...困難重重....」,這讓我非常的好奇,一心想看看在 Fedora 跟 Ubuntu 安裝都是瞬殺的 RMagick ,到底在 CentOS 上面出了啥問題。結果發現這條路好漫長,大概搞了半天以上吧......結論其實很簡單

    CentOS 預設 FreeType Lib 是爛掉的,重新 compile 即可。

    一開始我想看看RubyWorks ,因為他們有懶人包一次包好所有 Ruby on Rails 的東西。我發現到他們網站上面 Optional Package 宣稱他們有包好 RMagick
    rubygem-rmagick (librmagick-ruby in Debian/Ubuntu repository.) – interface between the Ruby programming language and the ImageMagick® and GraphicsMagick image processing libraries.
    但是我在 RubyWorks 的 yum 中找不到,所以就當沒有這東西存在。然後,使用 yum 安裝 ImageMagick ,再用 gem 安裝 RMagick ,發現 CentOS ImageMagick 的版本太舊,RMagick 2.0 不支援。

    下載最新的 IMageMagick ,然後用 gem 安裝 RMagick 看似沒問題,但是當我想測試一下,按下
    ruby -rrubygems -e "require 'RMagick'; puts Magick::Long_version;"
    就發現有許多 Error 等著我。當我把這些 Error 放到網路上,結果發現沒有幾個回答。大部分都是叫我回去看 RMagick 的 Install Note

    當然啦,別人叫我們看Install Note,就是代表「你並不了解這個東西」,所以我乖乖的看了一下我發現 RMagick 需要
    1. FreeType
    2. Ghostscript fonts
    3. JPEG
    4. PNG
    5. WMF
    這幾個 Image Lib ,當我確認過 CentOS 都有安裝這些 Lib 之後,很可惜的,Error 一再的出現,就這樣陷入了一再重複的地獄。最後我從這個網頁發現到

    CentOS 預設 FreeType Lib 是爛掉的。

    這就是最後的解答。So,請下載 FreeType 的 Lib ,重新 compile ,然後 RMagick 就會成功。

    以下是 Step by Step 安裝

    我在一台乾淨的 CentOS 上面安裝成功過。下面安裝版本,CentOS 5.1 + gcc 4.1.2 + ImageMagick 6.3.7 + FreeType 2.3.5 + rmagick 2.0 或是 rmagick 1.15.12。

    1. 安裝 GCC / G++
    yum install gcc-c++ compat-gcc-32 compat-gcc-32-c++

    2. Install 相關 lib
    yum install glib glib2 zlib-devel libpng libjpeg libtiff ghostscript

    3. 下載 FreeType 2.3.5 ,make

    4. 下載 ImageMagick,make
    你可以用 convert --version 確認是否安裝成功

    5. gem i rmagick
    你可以用
    ruby -rrubygems -e "require 'RMagick'; puts Magick::Long_version;"
    確認是否安裝成功。