<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5166551042886235322</id><updated>2012-01-29T03:37:02.929+08:00</updated><category term='Rubinius'/><category term='openid'/><category term='lighttpd'/><category term='postgresql'/><category term='採訪'/><category term='SQL'/><category term='news'/><category term='廣告'/><category term='vm'/><category term='介紹'/><category term='migrate'/><category term='beast'/><category term='pound'/><category term='ruby_binding'/><category term='activerdf'/><category term='passenger'/><category term='css'/><category term='push'/><category term='gem'/><category term='nginx'/><category term='rails'/><category term='rss'/><category term='performance'/><category term='xss'/><category term='vim'/><category term='erubis'/><category term='i18n'/><category term='fastcgi'/><category term='src_present'/><category term='mysql'/><category term='talk'/><category term='os'/><category term='security'/><category term='rmagick centos 安裝'/><category term='restful'/><category term='rdoc'/><category term='gettetx'/><category term='textmate'/><category term='gems'/><category term='gui'/><category term='case'/><category term='rest'/><category term='actionmailer'/><category term='心得'/><category term='mongrel'/><category term='html'/><category term='mac'/><category term='dsl'/><category term='memcached'/><category term='railsconf'/><category term='ria'/><category term='redmine'/><category term='ide'/><category term='Capistrano'/><category term='svn'/><category term='ruby'/><category term='activerecord'/><category term='acts_as_atggable'/><category term='planet'/><category term='cache'/><category term='irb'/><category term='http'/><category term='active_resource'/><category term='file_column'/><category term='rails12'/><category term='plugin'/><category term='shell'/><category term='functional'/><category term='rubyclr'/><category term='script'/><category term='windows'/><category term='layout'/><category term='railsconfEurope2006'/><category term='rake'/><category term='deploy'/><category term='apache'/><category term='嘴砲'/><category term='程式'/><category term='tiobe_index'/><category term='scale'/><category term='ajax'/><category term='yarv'/><category term='thin'/><category term='sqlite'/><category term='program'/><category term='比較'/><category term='book'/><category term='thread'/><category term='rails2.1'/><category term='pagination'/><category term='說明'/><category term='regex'/><category term='appserver'/><category term='company'/><category term='comet'/><category term='juggenaut'/><category term='安裝'/><category term='depoly'/><category term='quickref'/><category term='googlemap'/><category term='jruby'/><category term='jruby activerecord_jdbc'/><category term='ruby.net'/><category term='db'/><title type='text'>Lighty RoR</title><subtitle type='html'>介紹 Ruby，Ruby on Rails，JRuby</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default?start-index=101&amp;max-results=100'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>361</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-2689171381124584821</id><published>2009-01-09T17:49:00.006+08:00</published><updated>2009-01-09T18:08:09.669+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>ReCAPTCHA 與 ReCAPTCHA Rails Plugin</title><content type='html'>我們不管是註冊，或是去便當狗下載東西，都會有一張圖裡面有字，然後要你 keyin 正確的字。那個東西叫做 CAPTCHA。 CAPTCHA 是 ”Completely Automated Public Turing test to tell Computers and Humans Apart”的縮寫，主要用途是為了防止 robot Spam所做的手段。我看過最討厭，最難懂得 CAPTCHA 就是 Google 的 CAPTCHA，每次看都要硬猜個一兩次才會對，大概是他們整天被 Spam 攻擊，只好連真人都開始防堵 XD&lt;br /&gt;&lt;br /&gt;而什麼是 ReCAPTCHA 呢？ ReCAPTCHA 是卡內基美隆大學的一項計畫，由卡內基美濃學院資訊科學系執行。主要目的是為了加快實體文本數位化而作的一個手段，一般來說實體文本數位化需要的是數位掃描的技術，但是還是有很大量的書籍裡面的字礙誨難懂，有可能是紙張變質，也有可能是以前人的書寫習慣不公整（就是講我XD），這個時候就需要人力去辨識字的內容，並且給予機器正確的 return，順便 training 數位技術 Algorithm。很可惜的是，人力是要錢的。所以他們想出一個聰明到嚇死人的方式來處理這個問題。&lt;br /&gt;&lt;br /&gt;他們開發了一個網站，叫做 ReCAPTCHA 。裡面提供 CAPTCHA API ，讓網站開發者當需要 CAPTCHA 的技術時候，可以直接 Implement 這個 API，而不需要依賴自己重新開發 CAPTCHA 技術。他們並且號招很多志願者開發各種語言版本的 API，來加速網站開發者 implement ReCAPTCHA的速度。以下是 ReCAPTCHA 的截圖&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_8vS0KjIsbko/SWcd_15pizI/AAAAAAAAAqM/uj_ivt6IX9w/s1600-h/screen-capture-2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 127px;" src="http://2.bp.blogspot.com/_8vS0KjIsbko/SWcd_15pizI/AAAAAAAAAqM/uj_ivt6IX9w/s320/screen-capture-2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5289229270007778098" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;那為何他要免費提供這樣的服務呢？我們來仔細看他的技巧來自於 CAPTCHA 圖片本身，ReCAPTCHA 的圖片都是兩個英文字&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_8vS0KjIsbko/SWceGTGzLFI/AAAAAAAAAqU/Ize6oBtn3N0/s1600-h/Modern-captcha.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 300px; height: 57px;" src="http://2.bp.blogspot.com/_8vS0KjIsbko/SWceGTGzLFI/AAAAAAAAAqU/Ize6oBtn3N0/s320/Modern-captcha.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5289229380926778450" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;左邊的字 following 是他們已經確認掃描正確的字，右邊的 finding 是他們還無法用掃描確定意義的字。當使用者在 keying 認證碼的同時，他只要確定左邊的「following」是正確的，他們就認為是正確的 input，予以放行，但是使用者不是也 keyin 右邊的字嗎？那那個 input，ReCAPTCHA網站就視為你順手幫我做的影像校正，存到資料庫裡面。網站開發者免費得到 CAPTCHA 技術，ReCAPTCHA 獲得數以百萬記的免費人力幫忙校正，是個典型的雙贏局面。&lt;br /&gt;&lt;br /&gt;至於 Ruby 裡面有沒有 ReCAPTCHA API 呢？當然有。ReCAPTCHA for Ra ils 主頁在此。安裝方式就是&lt;br /&gt;&lt;br /&gt;&lt;div class="CodeRay"&gt;&lt;br /&gt;  &lt;div class="code"&gt;&lt;pre&gt;ruby script/plugin install git&lt;span style="color:#A60"&gt;:/&lt;/span&gt;/github.com/ambethia/recaptcha.git&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;安裝完成之後，你必須要先去 ReCAPTCHA 網站註冊，他會給你一個 PUB key 跟 Private key，將他記錄在 Rails 的 config/enviroment.rb 裡面&lt;br /&gt;&lt;br /&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;&lt;br /&gt;  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;2&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;&lt;br /&gt;  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="co"&gt;ENV&lt;/span&gt;[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;RECAPTCHA_PUBLIC_KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;] = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;public_key_goes_here&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;  &lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;span class="co"&gt;ENV&lt;/span&gt;[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;RECAPTCHA_PRIVATE_KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;]= &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;private_key_goes_here&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;接下來就是使用 ReCAPTCHA 啦，你要將 ReCAPTCHA 放在你需要的地方，這邊唯一要注意的地方在於你必須要放在 form 裡面&lt;br /&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;&lt;br /&gt;  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;&lt;br /&gt;  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&amp;lt;&lt;span class="s"&gt;&lt;span class="dl"&gt;%=&lt;/span&gt;&lt;span class="k"&gt; recaptcha_tags %&amp;gt;  &lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;接下來要驗證對方 keyin 的認證碼正不正確，我們只需要在相關的 controller 放入&lt;br /&gt;&lt;br /&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;&lt;br /&gt;  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;2&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;3&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;4&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;5&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;&lt;br /&gt;  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;if&lt;/span&gt; verify_recaptcha  &lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;span class="c"&gt;#正確的處理方式  &lt;/span&gt;&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;span class="r"&gt;else&lt;/span&gt;  &lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;span class="c"&gt;# 錯誤的處理方式  &lt;/span&gt;&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;   &lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;然後，沒啦，很簡單吧！！！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-2689171381124584821?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/2689171381124584821/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=2689171381124584821' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2689171381124584821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2689171381124584821'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2009/01/keyin-captcha-captcha-completely.html' title='ReCAPTCHA 與 ReCAPTCHA Rails Plugin'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_8vS0KjIsbko/SWcd_15pizI/AAAAAAAAAqM/uj_ivt6IX9w/s72-c/screen-capture-2.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-7370652566343789948</id><published>2008-12-26T17:31:00.001+08:00</published><updated>2008-12-26T17:32:37.118+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='file_column'/><title type='text'>File_Column 在 Rails 2.2 遇到問題以及解法</title><content type='html'>從&lt;a href="http://www.javaeye.com/topic/277860"&gt;這裡&lt;/a&gt;找到的解法，File_column 在升級 Rails 2.2 會遇到問題&lt;br /&gt;&lt;div class="CodeRay"&gt;&lt;br /&gt;  &lt;div class="code"&gt;&lt;pre&gt;uninitialized constant &lt;span style="color:#036; font-weight:bold"&gt;FileColumn&lt;/span&gt;::&lt;span style="color:#036; font-weight:bold"&gt;ClassMethods&lt;/span&gt;::&lt;span style="color:#036; font-weight:bold"&gt;Inflector&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;          &lt;br /&gt;解決方式就是找到 vender/plugins/file_column/lib/file_column.rb 的 619行&lt;br /&gt;&lt;div class="CodeRay"&gt;&lt;br /&gt;  &lt;div class="code"&gt;&lt;pre&gt;my_options = &lt;span style="color:#036; font-weight:bold"&gt;FileColumn&lt;/span&gt;::init_options(options,   &lt;br /&gt;                                      &lt;span style="color:#036; font-weight:bold"&gt;Inflector&lt;/span&gt;.underscore(&lt;span style="color:#038; font-weight:bold"&gt;self&lt;/span&gt;.name).to_s,  &lt;br /&gt;                                      attr.to_s) &lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;                                           &lt;br /&gt;改成     &lt;br /&gt;&lt;div class="CodeRay"&gt;&lt;br /&gt;  &lt;div class="code"&gt;&lt;pre&gt;my_options = &lt;span style="color:#036; font-weight:bold"&gt;FileColumn&lt;/span&gt;::init_options(options,&lt;br /&gt;                                           &lt;span style="color:#036; font-weight:bold"&gt;ActiveSupport&lt;/span&gt;::&lt;span style="color:#036; font-weight:bold"&gt;Inflector&lt;/span&gt;.underscore(&lt;span style="color:#038; font-weight:bold"&gt;self&lt;/span&gt;.name).to_s,&lt;br /&gt;                                           attr.to_s)    &lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;即可。主要原因是 Rails Core 漸漸有 Namespace 概念（不是本來就要有了嗎XD），所以之前可以 work 的 plugin code 現在都要修改成比較好的寫法。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7370652566343789948?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/7370652566343789948/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=7370652566343789948' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7370652566343789948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7370652566343789948'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/12/filecolumn-rails-22.html' title='File_Column 在 Rails 2.2 遇到問題以及解法'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-5534197892027483654</id><published>2008-12-24T15:52:00.001+08:00</published><updated>2008-12-24T15:53:45.564+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>金剛合體：Merb 將要 merge 到 Rails 3</title><content type='html'>&lt;p&gt;我以為 Rails 2.2 已經很有創意了，弄出很多新東西（or 應該做的東西） ，Rails 3 到底要做啥東西才能夠讓人家驚訝了呢？噹噹，我發現到 Rails 還是嚇到我了 。&lt;/p&gt;&lt;p&gt;Big news 就是 Merb 跟 Rails 3 預計在 2009 的 Rails conf Merge 起來，Merb 作者 wycats（ Yehuda Katz）會加入 Rails Team。請注意，我知道很瘋狂，不過這個消息已經經過 &lt;a href="http://weblog.rubyonrails.com/2008/12/23/merb-gets-merged-into-rails-3"&gt;Rails&lt;/a&gt; And &lt;a href="http://yehudakatz.com/2008/12/23/rails-and-merb-merge/"&gt;Merb&lt;/a&gt; 雙方證實了。&lt;/p&gt;&lt;p&gt;DHH 指出這次的 Merge 有幾點工作要做&lt;/p&gt;&lt;ol&gt; &lt;li&gt;Rails core：Rails 是一個 full stack framework ，不過他要參考 merb ，讓人很簡單的做出 rails myapp–core 和 rails myapp—flat&lt;/li&gt; &lt;li&gt;效能強化&lt;/li&gt; &lt;li&gt;Framework 解構：雖然 Rails 預設依舊是 ActiveRecord 當 ORM，不過你也可以選擇 data mapper，Sequel，Template 可以選擇 HAML，AJAX 可以選擇 jquery&lt;/li&gt; &lt;li&gt;Rigorous API：反正就是要解決 Rails 一升級 plugin 就炸掉的問題&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;怎麼看起來像是又生出一個 Merb ？&lt;/p&gt;&lt;p&gt;我來猜猜，DHH 認為 Merb 社群長久以來的堅持是對的，而 Rails 社群漸漸走錯路， DHH 眉頭一皺，認為案情並不單純，利用自己還很龐大的力量吃掉 Merb ，然後順便導正 Rails 該走的路。&lt;/p&gt;&lt;p&gt;It is not good news , and it is also not bad news，It's AMAZING news。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-5534197892027483654?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/5534197892027483654/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=5534197892027483654' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/5534197892027483654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/5534197892027483654'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/12/merb-merge-rails-3.html' title='金剛合體：Merb 將要 merge 到 Rails 3'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-3388369264197039145</id><published>2008-12-22T23:46:00.000+08:00</published><updated>2008-12-22T23:51:57.540+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Ruby Memory Leak 巨大問題以及解決方式</title><content type='html'>&lt;p&gt;Ruby Memory Leak 一向是一個難以解決的議題，不過在今年 11月12日的 &lt;a href="http://www.nabble.com/-ruby-core%3A19846---Bug--744--memory-leak-in-callcc--to20447794.html"&gt;Mailing List&lt;/a&gt; 裡面有人提出一個重要的問題， Ruby 的 callcc 在使用中產生相當明顯的 Memory Leak。後來有高手 &lt;a href="http://www.nabble.com/Re%3A--ruby-core%3A19945---Bug--744--memory-leak-in-callcc--p20533504.html"&gt;Brent Roman 發表他的發現&lt;/a&gt;。他原本再 ARM CPU 上面開發他的 Ruby Robot 程式（Ruby 1.6.8），他的機器人上面只有 32 MB 的 Memory，不過他的 Ruby 程式一天就會吃掉 20MB 的 Memory，經過他的 hack ，現在他的 Ruby 程式已經穩定在 10MB 以下，他發現 Ruby Memory Leak 很大部分在於 pointer ，跟 callcc 的使用上，Javaeye 上面有對於這個問題的&lt;a href="http://www.javaeye.com/news/4407-ruby-memory-leak-culprit---the-ghost-references-to-stack"&gt;詳細中文翻譯&lt;/a&gt;。&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Matz 知道之後，相當鼓勵 Brent 將他的 Patch 放到 Ruby 上面，如今他的 Patch 終於發佈，他是根據 Ruby 1.8.7-p72 做的 Patch ，又由於他在 Monterey Bay Aquarium Research Institute工作，所以叫做 &lt;a href="http://sites.google.com/site/brentsrubypatches/"&gt;1.8.7-p72 MBARI Patch&lt;/a&gt;，目前處於 Alpha 版本。他發現經過他的 hack 之後，對於 Memory Leak 上有相當大的解決。根據他的用 Ruby 預設的 Test Case 的結果，他發現 Memory 消耗從 97MB 降低到 57 MB，JavaEye 也利用他們的程式做測試，Javeeye Fcgi Memory 消耗量從 129MB 降低為 99MB。&lt;/p&gt;&lt;br /&gt;&lt;p&gt;相當不錯的結果，期待納入 Ruby 1.8.7 的那一天。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-3388369264197039145?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/3388369264197039145/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=3388369264197039145' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3388369264197039145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3388369264197039145'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/12/ruby-memory-leak.html' title='Ruby Memory Leak 巨大問題以及解決方式'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-8320744523912487506</id><published>2008-12-16T22:24:00.003+08:00</published><updated>2008-12-16T22:50:28.625+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Rails 2.2 在 Windows 上面有關 mysql Gem 的問題</title><content type='html'>今天要幫公司同事灌 Windows 上面 Rails ，發現安裝 mysql gem 出了點問題 ，本來是不用管，直接使用 Rails 附帶的 Mysql， 不過自從 Rails 2.2 之後，Rails 原本附帶的 mysql adaptor 已經移除掉adaptor，所以被迫得安裝 MySQL Gem 。&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#333333;"&gt;The bundled mysql.rb driver has been removed from rails 2.2.  Please&lt;br /&gt;install the mysql gem and try again: gem install mysql."&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;當我 gem i mysql，本來是沒問題的，不過現在不知道 gemspec 那裡改壞了，導致出現問題&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span"  style="color:#333333;"&gt;Installing ri documentation for mysql-2.7.3-x86-mswin32...&lt;br /&gt;Installing RDoc documentation for mysql-2.7.3-x86-mswin32...&lt;br /&gt;ERROR:  While generating documentation for mysql-2.7.3-x86-mswin32&lt;br /&gt;... MESSAGE:   Unhandled special: Special: type=17, text=""&lt;br /&gt;... RDOC args: --op&lt;/span&gt;&lt;!-- $Id:  README.html,v 1.20 2006-12-20 05:31:52 tommy Exp $ --&gt;&lt;/blockquote&gt;所以第一個問題解法就是不搞 RDOC，直接使用  &lt;b&gt;gem i mysql   --no-ri --no-rdoc &lt;span class="Apple-style-span" style="font-weight: normal; "&gt;安裝&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;當我以為已經解決的時候，沒想到出現第二個 Error&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span"  style="color:#333333;"&gt;This error occurred while loading the following files:    mysql&lt;/span&gt;&lt;/blockquote&gt;&lt;div&gt;靠，Rails 2.2 + Windows 還真多災多難，解決方式根據&lt;a href="http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/e6e656b52289ae45?pli=1"&gt;這裡&lt;/a&gt;，裡面說到要把 MySQL 帶的 libmysql.dll 複製一份過去到 ruby\bin 底下&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#333333;"&gt;copy mysql\bin\dll\libmysql.dll ruby\bin\&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;我使用的是 Instant Rails ，所以 MySQL 跟 Ruby 都放在同一個資料夾下面，如果安裝方式不同請自行處理。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8320744523912487506?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/8320744523912487506/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=8320744523912487506' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8320744523912487506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8320744523912487506'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/12/rails-22-windows-mysql-gem.html' title='Rails 2.2 在 Windows 上面有關 mysql Gem 的問題'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-7256175590294066383</id><published>2008-10-26T11:28:00.003+08:00</published><updated>2008-10-26T12:18:17.217+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Rails 2.2 ：多個願望一次達成...</title><content type='html'>購物專家：來來，我們現在請到 Rails 副總來本購物台，想請問副總對於這次 Ruby on Rails 2.2 來本台銷售，帶來了什麼好康。&lt;br /&gt;&lt;br /&gt;副總：這次的 Rails 2.2 可以說是本 Rails 產品史上最大的升級，可以說是把所有想的到聽的到看的到的問題都一次解決，保證這次不買你就是笨蛋，還去寫 PHP 或是 Java 只能祝福你。&lt;br /&gt;&lt;br /&gt;購物專家：啥，那麼可怕，那我想問問，有關之前被人詬病的 Rails &lt;span style="font-weight: bold;"&gt;國際化&lt;/span&gt;的部份有何加強。&lt;br /&gt;&lt;br /&gt;副總：記得上次我們來的時候怎麼講的？Rails 要國際化必須要 Gettext 或是 Plugin 來解決對不對。今天帶來的第一個優惠， Rails 2.2 直接&lt;span style="font-weight: bold;"&gt;內建 i18n&lt;/span&gt; 給你。如果有問題的話，請到&lt;a href="http://rails-i18n.org/"&gt;Rails i18n&lt;/a&gt;來看看怎麼實作。基本上是寫一個 yaml 就可以解決了。&lt;br /&gt;&lt;br /&gt;（罐頭歡呼聲）&lt;br /&gt;&lt;br /&gt;購物專家：什麼，直接內建 i18n ，那其他 Framework 不是少了一個古老的暴點可以笑 Rails 了嗎？你們上面業績衝的很兇歐，優惠送那麼大。那以前最讓人詬病的&lt;span style="font-weight: bold;"&gt;效能&lt;/span&gt;問題呢？&lt;br /&gt;&lt;br /&gt;副總：抱歉，其他家公司，你們災洗了。我們這次直接升級到&lt;span style="font-weight: bold;"&gt; Ruby 1.9&lt;/span&gt;，讓你們享受 19 倍的效率提昇。&lt;span style="font-style: italic; color: rgb(102, 102, 102);"&gt;（註：購物台都是隨便唬爛的，有提昇是沒錯，有沒有 19 倍就不知道XD）&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;（罐頭歡呼聲）&lt;br /&gt;&lt;br /&gt;購物專家：什麼什麼，你們直接支援效率打敗 Python 2.5 的 Ruby 1.9 呀，那不就是筆記型電腦加 Ram 再加 ssd 這樣誇張歐。這樣你們不會獲利下降嗎？&lt;br /&gt;&lt;br /&gt;副總：沒關係，只要可以服務購物台，我們可以流血犧牲&lt;br /&gt;&lt;br /&gt;購物專家：導播，各位觀眾，我已經快受不了，那麼好的優惠，那麼好的內容只在今天的 XX 購物台。現在電話所有線路忙線中，請改撥語音專線可以優先訂購。副總，已經端出那麼多了，還有啥好康的？&lt;br /&gt;&lt;br /&gt;副總：還有還有，我們改寫 ActiveRecord 了，支援 &lt;span style="font-weight: bold;"&gt;connection pool&lt;/span&gt; 摟，並且是 &lt;span style="font-weight: bold;"&gt;ThreadSafe&lt;/span&gt; 了。只要在 config/database.yml 裡面加上&lt;br /&gt;&lt;br /&gt;development:&lt;br /&gt;___adapter: mysql&lt;br /&gt;___username: root&lt;br /&gt;___database: sample_development&lt;br /&gt;___pool: 100&lt;br /&gt;___wait_timeout: 10&lt;br /&gt;&lt;br /&gt;就等於以 100 connection 讓 model 讀讓你取，效能提昇直接上看 100倍 &lt;span style="color: rgb(102, 102, 102);"&gt;（註：購物台都是隨便唬爛的，有提昇是沒錯，有沒有 100 倍就不知道XD）&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;（罐頭歡呼聲）&lt;br /&gt;&lt;br /&gt;購物專家：現在耳機傳來導播的聲音，現在我們備貨數量已經真的真的很少了，大家太踴躍了，記得撥打語音專線可以省一百塊歐。副總你們還有啥優惠嗎？&lt;br /&gt;&lt;br /&gt;副總：我們加入了 HTTP 的 &lt;span style="font-weight: bold;"&gt;last modified since&lt;/span&gt; 的 support，讓上次沒有修改過的內容就直接回傳一個 empty response 回去。原本是要回傳幾百K的東西，現在至需要回傳 0 K ，效能提昇直接上看&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;無限大&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;（註：購物台都是.....算了，懶得講了XD ）&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;（罐頭歡呼聲）&lt;br /&gt;（罐頭歡呼聲）&lt;br /&gt;（罐頭歡呼聲）&lt;br /&gt;&lt;br /&gt;副總：ㄟㄟㄟ，導播，我的購物專家勒？&lt;br /&gt;&lt;br /&gt;導播：他太激動了，回去學習 Ruby on Rails 了。&lt;br /&gt;&lt;br /&gt;副總：ㄟㄟㄟ，那麼猴急，我還沒講完勒，&lt;a href="http://guides.rubyonrails.org"&gt;http://guides.rubyonrails.org&lt;/a&gt; 上線了，可以直接上去看一些 online guilde。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;言歸正題，此次的 Rails 2.2 真的是超乎想像的加碼再加碼，修正了很多以前的問題，也加入相當多新的功能。&lt;br /&gt;&lt;br /&gt;1. i18n&lt;br /&gt;2. Ruby 1.9&lt;br /&gt;3. connection pool&lt;br /&gt;4. thread safe&lt;br /&gt;5. etag and last modified since&lt;br /&gt;&lt;br /&gt;真的可以說是史上最大的升級 XD&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7256175590294066383?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/7256175590294066383/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=7256175590294066383' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7256175590294066383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7256175590294066383'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/10/rails-22.html' title='Rails 2.2 ：多個願望一次達成...'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-3590423383931724592</id><published>2008-06-25T14:43:00.000+08:00</published><updated>2008-06-25T14:48:33.206+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='news'/><title type='text'>Python Hackthon 遭到保護動物組織的抗議</title><content type='html'>http://www.javaeye.com/news/2697&lt;br /&gt;&lt;br /&gt;http://techfaux.com/2008/06/17/peta-targets-computer-programmers-with-string-of-bizarre-protests/&lt;br /&gt;&lt;br /&gt;間單講就是好好的 Python Hackthon 聚會，闖入一堆 30位女生，突然全部脫光衣服，然後舉牌子「How many lives just for a coat?」，意思是要殺掉多少蛇才能有一件蛇皮大衣。&lt;br /&gt;&lt;br /&gt;這些天兵似乎還不知道自己在幹麼，她們大聲疾呼「We know what they’re doing in there.  They’re &lt;b&gt;hacking pythons&lt;/b&gt;.  It’s barbaric and we won’t leave until the last snake has been saved」，秀才遇到兵，有理說不清。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;改天 Ruby 聚會也有一堆人進來抗議，「停止虐待採紅寶石的勞工」怎麼辦....&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-3590423383931724592?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/3590423383931724592/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=3590423383931724592' title='6 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3590423383931724592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3590423383931724592'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/06/python-hackthon.html' title='Python Hackthon 遭到保護動物組織的抗議'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-1084853483530650614</id><published>2008-06-06T13:56:00.002+08:00</published><updated>2008-06-06T13:59:12.179+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gems'/><category scheme='http://www.blogger.com/atom/ns#' term='rails2.1'/><title type='text'>Rails 2.1 新特色：打包 Gem</title><content type='html'>&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;顧客：&lt;/span&gt;&lt;/span&gt;老闆， Web 2.0 網站一份，Rails 要 2.1 的，還有幫我加香菜，還有所有的 Gem Package 都要包在一起，要快點，等等 10分鐘要上 Production Server。&lt;div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;老闆：&lt;/span&gt;&lt;/span&gt;好好好，馬上來，要不要順便叫個啤酒呀？&lt;br /&gt;&lt;br /&gt;Rails 2.1 加入了一個新功能&lt;a href="http://ryandaigle.com/articles/2008/4/1/what-s-new-in-edge-rails-gem-dependencies" title="Ryan's Scraps: What's New in Edge Rails: Gem Dependencies"&gt; Gem Dependencies&lt;/a&gt; ，相當的優。像是上述需求，只需要下達&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt; $ rake rails:freeze:edge&lt;br /&gt; $ vi config/environment.rb&lt;br /&gt; $ rake gems:unpack&lt;br /&gt; $ rake gems:build&lt;br /&gt;&lt;/blockquote&gt;即可完成將 Rails 原始碼，Gems 原始碼包入到 Rails app folder 裡面，這樣 deploy 超方便呀。&lt;/div&gt;&lt;div&gt;   &lt;br /&gt;&lt;strong&gt;以下是詳細解說&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;$ rake rails:freeze:edge&lt;br /&gt;把現在的Rails Version 打包入 vender/rails/&lt;br /&gt;&lt;br /&gt;$ vi config/environment.rb&lt;br /&gt;把所有有關的 Gem package 加入設定檔 &lt;br /&gt;&lt;div class="CodeRay"&gt;&lt;br /&gt; &lt;div class="code"&gt;&lt;pre&gt;&lt;span style=" font-weight:bold;color:#036;"&gt;Rails&lt;/span&gt;::&lt;span style=" font-weight:bold;color:#036;"&gt;Initializer&lt;/span&gt;.run &lt;span style=" font-weight:bold;color:#080;"&gt;do&lt;/span&gt; |config|&lt;br /&gt;&lt;br /&gt; &lt;span style="color:#888;"&gt;# Require the latest version of haml&lt;/span&gt;&lt;br /&gt; config.gem &lt;span style="background-;color:#fff0f0;"&gt;&lt;span style="color:#710;"&gt;"&lt;/span&gt;&lt;span style="color:#D20;"&gt;haml&lt;/span&gt;&lt;span style="color:#710;"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span style="color:#888;"&gt;# Require a specific version of chronic&lt;/span&gt;&lt;br /&gt; config.gem &lt;span style="background-;color:#fff0f0;"&gt;&lt;span style="color:#710;"&gt;"&lt;/span&gt;&lt;span style="color:#D20;"&gt;chronic&lt;/span&gt;&lt;span style="color:#710;"&gt;"&lt;/span&gt;&lt;/span&gt;, &lt;span style="color:#A60;"&gt;:version&lt;/span&gt; =&amp;gt; &lt;span style="background-;color:#fff0f0;"&gt;&lt;span style="color:#710;"&gt;'&lt;/span&gt;&lt;span style="color:#D20;"&gt;0.2.3&lt;/span&gt;&lt;span style="color:#710;"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span style="color:#888;"&gt;# Require a gem from a non-standard repo&lt;/span&gt;&lt;br /&gt; config.gem &lt;span style="background-;color:#fff0f0;"&gt;&lt;span style="color:#710;"&gt;"&lt;/span&gt;&lt;span style="color:#D20;"&gt;hpricot&lt;/span&gt;&lt;span style="color:#710;"&gt;"&lt;/span&gt;&lt;/span&gt;, &lt;span style="color:#A60;"&gt;:source&lt;/span&gt; =&amp;gt; &lt;span style="background-;color:#fff0f0;"&gt;&lt;span style="color:#710;"&gt;"&lt;/span&gt;&lt;span style="color:#D20;"&gt;http://code.whytheluckystiff.net&lt;/span&gt;&lt;span style="color:#710;"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span style="color:#888;"&gt;# Require a gem that needs to require a file different than the gem's name&lt;/span&gt;&lt;br /&gt; &lt;span style="color:#888;"&gt;# I.e. if you normally load the gem with require 'aws/s3' instead of&lt;/span&gt;&lt;br /&gt; &lt;span style="color:#888;"&gt;# require 'aws-s3' then you would need to specify the :lib option&lt;/span&gt;&lt;br /&gt; config.gem &lt;span style="background-;color:#fff0f0;"&gt;&lt;span style="color:#710;"&gt;"&lt;/span&gt;&lt;span style="color:#D20;"&gt;aws-s3&lt;/span&gt;&lt;span style="color:#710;"&gt;"&lt;/span&gt;&lt;/span&gt;, &lt;span style="color:#A60;"&gt;:lib&lt;/span&gt; =&amp;gt; &lt;span style="background-;color:#fff0f0;"&gt;&lt;span style="color:#710;"&gt;"&lt;/span&gt;&lt;span style="color:#D20;"&gt;aws/s3&lt;/span&gt;&lt;span style="color:#710;"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=" font-weight:bold;color:#080;"&gt;end&lt;/span&gt;       &lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;      &lt;br /&gt;$ rake gems:unpack&lt;br /&gt;把所有的 config 裡面設定相關的 Gem Package 都打包入 vender/gems/&lt;br /&gt;&lt;br /&gt;$ rake gems:build&lt;br /&gt;非一定要用，只是如果你相關的 gem package 不一定是純 Ruby Code，有些會相關一些 C Lib，這時候就可以用這個指令來 build native gems。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1084853483530650614?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/1084853483530650614/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=1084853483530650614' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1084853483530650614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1084853483530650614'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/06/rails-21-gem.html' title='Rails 2.1 新特色：打包 Gem'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-4336241766301146222</id><published>2008-06-05T17:15:00.001+08:00</published><updated>2008-06-05T17:15:50.572+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='gettetx'/><title type='text'>Gettext 在 Rails 2.1 下面的問題</title><content type='html'>Gettext 1.19 遇到 Rails 2.1 會發生以下的問題&lt;br /&gt;&lt;blockquote&gt;NoMethodError (undefined method `file_exists?' for #):&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;解決方式就是寫一個 config/initializers/gettext.rb &lt;br /&gt;&lt;div class="CodeRay"&gt;&lt;br /&gt;  &lt;div class="code"&gt;&lt;pre&gt;require &lt;span style="background-color:#fff0f0"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style="color:#D20"&gt;gettext/rails&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#080; font-weight:bold"&gt;module&lt;/span&gt; &lt;span style="color:#B06; font-weight:bold"&gt;ActionView&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:#080; font-weight:bold"&gt;class&lt;/span&gt; &lt;span style="color:#B06; font-weight:bold"&gt;Base&lt;/span&gt;&lt;br /&gt;    delegate &lt;span style="color:#A60"&gt;:file_exists?&lt;/span&gt;, &lt;span style="color:#A60"&gt;:to&lt;/span&gt; =&amp;gt; &lt;span style="color:#A60"&gt;:finder&lt;/span&gt; &lt;span style="color:#080; font-weight:bold"&gt;unless&lt;/span&gt; respond_to?(&lt;span style="color:#A60"&gt;:file_exists?&lt;/span&gt;)&lt;br /&gt;  &lt;span style="color:#080; font-weight:bold"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#080; font-weight:bold"&gt;end&lt;/span&gt;      &lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;          &lt;br /&gt;重起即可。&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4336241766301146222?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/4336241766301146222/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=4336241766301146222' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4336241766301146222'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4336241766301146222'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/06/gettext-rails-21.html' title='Gettext 在 Rails 2.1 下面的問題'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-6914874850947900038</id><published>2008-05-01T08:46:00.001+08:00</published><updated>2008-05-01T08:46:09.363+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Rails 2.1 RC Release</title><content type='html'>Rails 學習之路最困難的一件事就是，社群活力太強，改版太快了。&lt;a href="http://weblog.rubyonrails.com/2008/4/30/rails-2-1-release-candidate-is-imminent"&gt;Rails 2.1 RC Release了&lt;/a&gt;。請到Rails最新時尚的 github 去取用。              &lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6914874850947900038?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/6914874850947900038/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=6914874850947900038' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6914874850947900038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6914874850947900038'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/05/rails-21-rc-release.html' title='Rails 2.1 RC Release'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-1515788631775569590</id><published>2008-04-22T16:14:00.000+08:00</published><updated>2008-04-22T16:21:33.752+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>把某資料夾的 UTF8 檔案轉成 Big5</title><content type='html'>不要問我為何如此，反正 TextMate + 只能用Big5的Project 造成的。&lt;br /&gt;&lt;br /&gt;&lt;div class="CodeRay"&gt;&lt;br /&gt;  &lt;div class="code"&gt;&lt;pre&gt;pwd = &lt;span style="background-color:#f0fff0"&gt;&lt;span style="color:#161"&gt;`&lt;/span&gt;&lt;span style="color:#2B2"&gt;pwd&lt;/span&gt;&lt;span style="color:#161"&gt;`&lt;/span&gt;&lt;/span&gt;.chop&lt;br /&gt;all_files = &lt;span style="background-color:#f0fff0"&gt;&lt;span style="color:#161"&gt;`&lt;/span&gt;&lt;span style="color:#2B2"&gt;find app -type f -not -regex &amp;quot;.*.svn.*&amp;quot;&lt;/span&gt;&lt;span style="color:#161"&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;all_files.each &lt;span style="color:#080; font-weight:bold"&gt;do&lt;/span&gt; |file| &lt;br /&gt;old_file = pwd+&lt;span style="background-color:#fff0f0"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;/&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;+file.chop&lt;br /&gt;new_file = pwd+&lt;span style="background-color:#fff0f0"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;/big5/&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;+file.chop&lt;br /&gt;&lt;span style="background-color:#f0fff0"&gt;&lt;span style="color:#161"&gt;`&lt;/span&gt;&lt;span style="color:#2B2"&gt;iconv -f utf-8 -t big5 &lt;/span&gt;&lt;span style="background: #eee"&gt;&lt;span style="font-weight: bold; color: #888"&gt;#{&lt;/span&gt;old_file&lt;span style="font-weight: bold; color: #888"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#2B2"&gt; &amp;gt; &lt;/span&gt;&lt;span style="background: #eee"&gt;&lt;span style="font-weight: bold; color: #888"&gt;#{&lt;/span&gt;new_file&lt;span style="font-weight: bold; color: #888"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#161"&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#080; font-weight:bold"&gt;end&lt;/span&gt;        &lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1515788631775569590?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/1515788631775569590/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=1515788631775569590' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1515788631775569590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1515788631775569590'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/04/utf8-big5.html' title='把某資料夾的 UTF8 檔案轉成 Big5'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-5995552012838764468</id><published>2008-04-12T16:01:00.002+08:00</published><updated>2008-04-13T19:24:26.452+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='passenger'/><title type='text'>Passenger ：Mod_rails for Apache 終於出世</title><content type='html'>這是 Rails 登基的最後一塊基石嗎？&lt;br /&gt;&lt;br /&gt;不知道說了多少次，Apache 上面沒有 mod_rails，不能像是 php 一樣放上去就跑了，不過時代終於改變了，Mod_rails 出現了，他的名字叫做 &lt;a href="http://www.modrails.com/index.html" title="Overview — Phusion Passenger (a.k.a. mod_rails)"&gt;Passenger&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;他做的事情就是讓設定Ruby on Rails &lt;strong&gt;簡單到極點&lt;/strong&gt;，省去所有設定繁複的設定手續，一個 Apache 就可以跑 Ruby on Rails。讓所有覺得 Ruby on Rails 設定困難的人全部閉嘴。 此東西一出，各方高手可&lt;a href="http://www.modrails.com/testimonials.html"&gt;都是讚譽有加&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;DHH : This could definitely become very popular, very fast ;)&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;效能&lt;/strong&gt;&lt;br /&gt;第一個問題是他的效能跟穩定性，跟現在市面上的 solution 有沒有得比。&lt;br /&gt;&lt;br /&gt;根據他們&lt;a href="http://izumi.plan99.net/blog/index.php/2008/03/31/benchmark-passenger-mod_rails-vs-mongrel-vs-thin/" title="赖洪礼的 blog » Benchmark: Passenger (mod_rails) vs Mongrel vs Thin"&gt;自己的測試&lt;/a&gt;，看來是有大於 Mongrel，略贏過於 Thin 的效能。 &lt;a href="http://ninh.nl/blog/2008/04/07/robustness-comparison-between-phusion-passenger-thin-ebb-and-mongrel/" title="Ninh’s Weblog  » Blog Archive   » Robustness comparison between Phusion Passenger, Thin, Ebb and Mongrel"&gt;Robustness 測試&lt;/a&gt;他們宣稱跟 Mongrel 一樣穩定，勝過 thin 還有 ebb。&lt;br /&gt;                &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_8vS0KjIsbko/SAHtUwqMpmI/AAAAAAAAARE/YvnyPesfZoo/s1600-h/passenger_mongrel_thin_benchmark.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_8vS0KjIsbko/SAHtUwqMpmI/AAAAAAAAARE/YvnyPesfZoo/s320/passenger_mongrel_thin_benchmark.png" alt="" id="BLOGGER_PHOTO_ID_5188689186622580322" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;安裝方式&lt;/strong&gt;&lt;br /&gt;既然是走簡單取向的 Apache ，那安裝方式當然要簡單點摟。只要你的 Server 上面有 Ruby / Rails / Gems / Apache2 ，那麼安裝方式就是兩下&lt;br /&gt;1. gem i passenger&lt;br /&gt;2. passenger-install-apache2-module&lt;br /&gt; &lt;br /&gt;&lt;strong&gt;設定方式&lt;/strong&gt;&lt;br /&gt;既然是走簡單取向，設定方式要更簡單，你必須在 Apache 的 httpd.conf 裡面設定&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt; LoadModule passenger_module passenger_module的預設目錄&lt;br /&gt; RailsSpawnServer SpawnServer路徑&lt;br /&gt; RailsRuby ruby路徑 &lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;別擔心找不到相關路徑，&lt;br /&gt;&lt;img src="http://farm3.static.flickr.com/2132/2407370926_5c8c2632b6.jpg" alt="screen-capture.png" width="480" height="343" /&gt;&lt;br /&gt;上面的圖，我們可以看到在 passenger-install-apache2-module 過程中他會自動產生相關設定檔，給你貼上去。&lt;br /&gt;&lt;br /&gt;剛剛是把 Rails 環境設定好，現在就是就是設定 DocumentRoot，&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt; &amp;lt;VirtualHost *:80&gt;&lt;br /&gt;       ServerName www.yourhost.com&lt;br /&gt;       DocumentRoot /rails目錄/public&lt;br /&gt; &amp;lt;/VirtualHost&gt; &lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;簡單講就是要設定清楚 Document Root，設定到Rails 目錄底下的 public 資料夾。，當然他也有範例 config 檔自動生成 XD&lt;br /&gt;&lt;img src="http://farm3.static.flickr.com/2269/2406546183_0f5d0ccbe5.jpg" alt="screen-capture-1.png" width="480" height="350" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;讓 Rails 跑在子目錄下&lt;/strong&gt;&lt;br /&gt;還沒測試，不過在 &lt;a href="http://www.modrails.com/documentation/Users%20guide.html#specifying_ruby_installation" title="Passenger users guide"&gt;Doc&lt;/a&gt; 裡面有，看來可以很簡單的跑 PHP 跟 Rails 在同一個 Apache 下面(Bravo！！！)。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;原理&lt;/span&gt;&lt;br /&gt;採用類似 Apache mod_fastcgi 的方式，以一個 Passenger Process 來管理所需的 Rails process 量，隨著量的大小而動態增減 Process 數目。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;結論&lt;/strong&gt;&lt;br /&gt;目前沒有明顯的結論，說 Passenger 一定勝過 Mongrel 或是 Lighttpd+fcgi 的 Solution。不過，看到他簡單的設定檔，還有看似不錯的效能跟穩定度，真的很值得期待。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-5995552012838764468?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/5995552012838764468/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=5995552012838764468' title='4 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/5995552012838764468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/5995552012838764468'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/04/modrails-passenger-release.html' title='Passenger ：Mod_rails for Apache 終於出世'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_8vS0KjIsbko/SAHtUwqMpmI/AAAAAAAAARE/YvnyPesfZoo/s72-c/passenger_mongrel_thin_benchmark.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-8773854125643035393</id><published>2008-04-08T08:05:00.001+08:00</published><updated>2008-04-08T08:05:13.326+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='textmate'/><title type='text'>解決 Textmate 中文問題</title><content type='html'>沒想到我也會寫這種教學，不過既然有人問就順便講一下啦。嚴格說起來，我完全是參照&lt;a href="http://blog.roodo.com/shinbang/archives/3264563.html"&gt;這篇網頁&lt;/a&gt;所教學的方式。&lt;br /&gt;&lt;br /&gt;Textmate 對中文的實在爛到不知道怎麼說，主要有兩個問題&lt;br /&gt;1. 沒有中文字型&lt;br /&gt;2. 不能顯示出輸入法提示列&lt;br /&gt;&lt;br /&gt;要解決&lt;strong&gt;沒有中文字型&lt;/strong&gt;的方式就是安裝中文字即可，請下載&lt;a href="http://www.esnips.com/doc/f5bb5cf6-663f-46e6-80cb-0cba549c7cda/TextMateJ2"&gt; TextMateJ2&lt;/a&gt; 這個字型。複製到 /System/Library/Fonts/ 底下，並且雙擊安裝。安裝字型之後，就是要選擇這個字型，請到 TextMate 的 Preference -&gt; Fonts and Colors 最下面的字型裡面選擇 TextMateJ2。&lt;br /&gt;&lt;br /&gt;&lt;img src="http://farm4.static.flickr.com/3240/2397460114_f936cf1ef3.jpg" width="399" height="480" alt="screen-capture.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;要解決&lt;strong&gt;不能顯示輸入法提示列&lt;/strong&gt;就是安裝 &lt;a href="http://hetima.com/textmate/CJKInput20061110.zip"&gt;CJK-Input.tmplugin&lt;/a&gt; 。解開後就直接點 CJK-Input.tmplugin，他好像就會直接安裝了。   &lt;br /&gt;&lt;br /&gt;成品就是如底下圖。字型會擠擠的，這是沒辦法的事情。唯一解決方案就是等 TextMate 2 出。&lt;br /&gt;&lt;img src="http://farm3.static.flickr.com/2170/2396628569_996a62a13a.jpg" width="480" height="237" alt="screen-capture-1.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8773854125643035393?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/8773854125643035393/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=8773854125643035393' title='4 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8773854125643035393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8773854125643035393'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/04/textmate.html' title='解決 Textmate 中文問題'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3240/2397460114_f936cf1ef3_t.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-4339757928161150773</id><published>2008-04-08T00:10:00.000+08:00</published><updated>2008-04-08T07:46:45.363+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><title type='text'>JRuby 1.1 Release</title><content type='html'>JRuby 1.1 已經 Release 了，1.0到1.1最主要的不同是在「效能」的成長。JRuby 1.1 在很多 Benchmark 已經超越了 Ruby 1.8，甚至有些也贏過了Ruby 1.9。主要的修改有        &lt;br /&gt;&lt;br /&gt;1. Ruby code 可以 compile 成 Java Bytecode&lt;br /&gt;2. Regular expression engine 改成 Oniguruma&lt;br /&gt;3. 效能的進步以及相容性的進步&lt;br /&gt;&lt;br /&gt;Ruby compile 成 Java Bytecode 一共有兩種模式（AOT或是JIT mode）。        &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;JIT Mode &lt;/strong&gt;是預設，代表他會經過一段時間才會運轉到 compile Mode ， &lt;a href="http://wiki.jruby.org/wiki/JRuby_Internal_Design"&gt;JRuby Wiki&lt;/a&gt; 建議是 跑20次就自動到 JIT Mode 去。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;AOT Mode&lt;/strong&gt; 可以將 Ruby code compile 成 Java 的 .class 檔案。如果想要直接用 Java 去執行，要裝 JRuby.jar ，還有 asm-3.0.jar ，jna.jar。      &lt;br /&gt;&lt;br /&gt;下載連結：&lt;a href="http://dist.codehaus.org/jruby/jruby-bin-1.1.zip"&gt;http://dist.codehaus.org/jruby/jruby-bin-1.1.zip&lt;/a&gt;     &lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4339757928161150773?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/4339757928161150773/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=4339757928161150773' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4339757928161150773'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4339757928161150773'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/04/jruby-11-release.html' title='JRuby 1.1 Release'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-4794296834900282928</id><published>2008-04-04T18:24:00.001+08:00</published><updated>2008-04-04T18:24:49.070+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='textmate'/><title type='text'>更換主力 Editor ，改成 TextMate</title><content type='html'>這是一個困難的決定，不過是一個對的決定。&lt;br /&gt;&lt;br /&gt;當我被某人勸說，不小心 Download 下來 TextMate 試用，彷彿打開所謂的禁忌之門，不久我就淪陷啦。我已經正式切換到 TextMate 上面了，vim 已經被冷落一週以上了。&lt;br /&gt;&lt;br /&gt;你問我 textmate 好在哪裡，我只能說調性很合我的感覺。&lt;br /&gt;&lt;br /&gt;是的，他有一卡車的缺點。這是我第一個花錢買的 Editor，第一個遇到居然連 Big5 都不能編輯的 Editor(他只接受 Unicode)，也就是我要用 Vim 繼續處理 Big5 的 Project @@!。第一個連打中文字都要 Plugin 的軟體。&lt;br /&gt;&lt;br /&gt;不過，該怎麼說呢。&lt;br /&gt;&lt;br /&gt;Vim 是初戀情人，我用他用了5年，他對我有滿滿的回憶。Textmate 就是有很多缺點，但是卻愛的死心塌地，愛的轟轟烈烈的愛人吧。&lt;br /&gt;&lt;br /&gt;如果這就是愛&lt;br /&gt;在轉身就該勇敢留下來&lt;br /&gt;就算受傷　就算流淚&lt;br /&gt;都是生命裡溫柔灌溉～～～  出自『如果愛」這首歌&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4794296834900282928?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/4794296834900282928/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=4794296834900282928' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4794296834900282928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4794296834900282928'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/04/editor-textmate.html' title='更換主力 Editor ，改成 TextMate'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-8718048202064159668</id><published>2008-04-04T02:45:00.008+08:00</published><updated>2008-04-04T04:59:15.971+08:00</updated><title type='text'>Rack - 小架子立大功</title><content type='html'>最近  Ruby Web Framework 界出現了很多新面孔：&lt;br /&gt;&lt;a href="http://ramaze.net/"&gt;Ramze&lt;/a&gt;, &lt;a href="http://sinatra.rubyforge.org/"&gt;Sinatra&lt;/a&gt;,&lt;a href="http://rubywaves.com"&gt;Waves&lt;/a&gt;, &lt;a href="http://halcyon.rubyforge.org/"&gt;Halcyon&lt;/a&gt; ，還有  4/1 才發佈的下一代 framework ==&gt; &lt;a href="http://antoniocangiano.com/2008/04/01/announcing-ruby-on-crack/"&gt;Ruby on Crack!!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;這些 framework 各有各的特點，除了為原本被 Rails 一統天下的 web 開發增添了新的風貌，也說明了 Ruby 社群的活躍。而他們(除了太神奇的 Crack 之外)的背後的大功臣，就是今天的主題： &lt;b&gt;&lt;a href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt;&lt;/b&gt;。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Rack 到底是何方神聖呢？&lt;/h3&gt;&lt;br /&gt;每個  web framework 最後一定要接回去 web server 。方法有很多，有人喜歡老牌的 Fastcgi ，有人愛用&lt;a href="http://mongrel.rubyforge.org/"&gt;雜種狗&lt;/a&gt;，有人要像 mac book air 一樣&lt;a href="http://code.macournoyer.com/thin/"&gt;薄&lt;/a&gt;，有人說&lt;a href="http://ebb.rubyforge.org/"&gt;退潮&lt;/a&gt;最快。&lt;br /&gt;&lt;br /&gt;新的 framework 一直冒，新的 web server 一直來，每個人都要重新寫把兩者接起來的 code 實在太累了， Rack 就是為了解決這個問題而出現的。&lt;a href='#footnote1' style="font-size:60%;"&gt;(1)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/23796678@N04/2385302361/" title="Flickr 上 donkeydragbamboo 的 Rack"&gt;&lt;img src="http://farm3.static.flickr.com/2251/2385302361_39aafe237b.jpg" width="400" height="256" alt="Rack" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Web 程式講白了很簡單，就是拿 request 然後回 response。Rack 就是把各種 web server 的 request 和各種  framewrok 的 response 用統一的介面來處理。那麼這個統一的介面是什麼呢？&lt;br /&gt;&lt;br /&gt;一句話&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;br /&gt;&lt;span style='color:#400000; '&gt;lambda&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt; |env| &lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#008c00; '&gt;200&lt;/span&gt;, &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;, 'Hello World!' }&lt;/pre&gt;&lt;br /&gt;首先， Rack 會將 request 傳給要處理這個 request 的物件的 call 函式。這個例子中，處理 request 的物件就是 lambda。(當然你可以用一般的物件，只要它有 call  這個  method 就行了。)&lt;br /&gt;例子中的 env 就是 request，它是一個 hash ，裡面包含了類似 CGI Environment 變數，像是 PATH_INFO，QUERY_STRING 等等的東西。&lt;br /&gt;&lt;br /&gt;而 call 的回傳值，會被當成 response 傳回去給 web server。這個回傳值必需是包含三個元素的 Array： status, headers 和 body。&lt;br /&gt;&lt;br /&gt;原本 N 個 framework 和 M 個 web server ，要寫出 NxM 個 Adapter。而有了 Rack 後，大家只要對 Rack 的介面做 Adapter ，複雜度馬上減少為 N+M 了！&lt;br /&gt;&lt;br /&gt;如此一來，不用一直重新實做橋接的邏輯，可以把心思放在 framework 本身的設計上。有了 rack ，相信 ruby 的 web 開發會更為有趣。&lt;br /&gt;&lt;br /&gt;下一篇再來實際寫些 code 吧。&lt;br /&gt;&lt;br /&gt;&lt;a name='footnote1' &gt;&lt;/a&gt;&lt;br /&gt;這張圖的 idea 是從&lt;a href="http://macournoyer.wordpress.com/2007/12/14/rack-the-framework-framework/"&gt;這裡&lt;/a&gt;來的...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8718048202064159668?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/8718048202064159668/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=8718048202064159668' title='4 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8718048202064159668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8718048202064159668'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/04/rack.html' title='Rack - 小架子立大功'/><author><name>contagion</name><uri>http://www.blogger.com/profile/13677354681517903830</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2048/1808481797_c2339dd049_s.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2251/2385302361_39aafe237b_t.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-1426280925841579742</id><published>2008-04-01T08:49:00.000+08:00</published><updated>2008-04-01T08:50:01.810+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='talk'/><title type='text'>[連結文] 為何有些 Java EE/J2EE 的專案是沒效率的，至少是效率低下的</title><content type='html'>&lt;a href="http://www.adam-bien.com/roller/abien/entry/why_some_of_the_java"&gt;原文連結&lt;/a&gt;在此，要看&lt;a href="http://www.javaeye.com/topic/177070?page=1"&gt;簡體翻譯&lt;/a&gt;在此。光是第一句我就笑死了。&lt;br /&gt;&lt;br /&gt;我想到一句話，「教授是將簡單的事情變得很複雜，天才是把複雜的事情變得很簡單」。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1426280925841579742?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/1426280925841579742/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=1426280925841579742' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1426280925841579742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1426280925841579742'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/04/java-eej2ee.html' title='[連結文] 為何有些 Java EE/J2EE 的專案是沒效率的，至少是效率低下的'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-8426848800027779300</id><published>2008-03-31T16:34:00.002+08:00</published><updated>2008-03-31T16:35:37.344+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Rails 2.0 使用 Big5 編碼</title><content type='html'>沒想到我的有生之年居然還會使用到 Big5!!!&lt;br /&gt;&lt;br /&gt;沒錯，基於機緣巧合，我碰到了一個需要使用 Big5 資料庫，網頁也是 Big5 顯示的request。所以我必須匿天而行，強迫 Rails 2.0 使用 Big5。方法很簡單，&lt;br /&gt;&lt;br /&gt;config/enviroment.rb 裡面加入&lt;br /&gt;  config.action_controller.default_charset = "Big5"&lt;br /&gt;&lt;br /&gt;config/database.yml記得加入&lt;br /&gt;development:&lt;br /&gt;    host: xxx&lt;br /&gt;    adapter: mysql&lt;br /&gt;    database: lala&lt;br /&gt;    port: 3306&lt;br /&gt;    username: root&lt;br /&gt;    password: &lt;br /&gt;    encoding: Big5&lt;br /&gt;&lt;br /&gt;Html 記得加入 &lt;br /&gt;  &amp;lt;meta http-equiv="content-type" content="text/html;charset=Big5" /&gt;&lt;br /&gt;&lt;br /&gt;大概就這樣吧，我抱著參觀懷舊的心情來寫這個網頁 XD&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8426848800027779300?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/8426848800027779300/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=8426848800027779300' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8426848800027779300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8426848800027779300'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/03/rails-20-big5.html' title='Rails 2.0 使用 Big5 編碼'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-8482102368286293911</id><published>2008-03-20T11:56:00.002+08:00</published><updated>2008-03-20T12:10:45.271+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><title type='text'>Rails 2.0 比起 Rails 1.2 加速不少</title><content type='html'>好像是一個對岸人赖洪礼 在自己 blog 發表一篇&lt;a href="http://izumi.plan99.net/blog/index.php/2008/03/18/performance-comparison-rails-126-vs-202/"&gt;壓力測試&lt;/a&gt;。他發現到 Rails 2.0 比起 Rails 1.2 加速不少，大概是 30%~50%。不過，他的測試方式相當的原始，用 ab 去量 scaffold 頁面的 req/sec。所以數字比例根本不能做准。&lt;br /&gt;&lt;br /&gt;但是，至少說明 Rails Team 有在為了 performance 盡力，並且有實際的成果。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8482102368286293911?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/8482102368286293911/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=8482102368286293911' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8482102368286293911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8482102368286293911'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/03/rails-20-rails-12.html' title='Rails 2.0 比起 Rails 1.2 加速不少'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-4651239897265249160</id><published>2008-03-15T12:11:00.001+08:00</published><updated>2008-03-15T12:11:31.257+08:00</updated><title type='text'>Netbeans 6 相當的威</title><content type='html'>&lt;p&gt;前陣子需要一個 IDE 來教課，需求如下&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;  &lt;li&gt;好安裝&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;跟 Rails 整合良好&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;就選了 Netbeans 6 來試試看，結果發現真的還蠻不錯的，因為都是 Sun 的東西，所以直接跟 jruby 有很好的整合&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Navigation 還不錯用，可以直接跑到這個 Controller 相關的 View，或是這個 View 相關的 Controller ，也可以指到這個 Class 宣告的地方。&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;內建 svn ，也比 Eclipse 還得裝 SubEclipse 來的方便。&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;內建 jruby ，也可以直接包成 war file&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Find Usage 可以找出所有使用這個 class 的程式碼所在，主要找出所有使用這個 Model 的 Controller 列表&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;內建 mysql GUI Tool&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Code Hint 超棒&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;最重要的是，他可以直接把 Model 對應到 attribute 給取出來&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://farm4.static.flickr.com/3296/2334510284_58f6572262.jpg" width="480" height="163" alt="activerecord6.png" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Product Model 裡面有 description，image_url ... title 等 table column ，Netbeans 6 可以直接取出來放到 code hint 裡面去。這樣就省了點找 db column 的時間了。不過這個功能必須使用 migration ，或是將 db schema dump 到 schema.rb 才可以用，也就是說不是 live db connection 去取 schema 啦。&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Netbeans 6 最大的缺點就是速度太慢了.......，不過 6.1 Beta 已經改善了不少。大家可以試試看。&lt;/p&gt;&lt;br /&gt;&lt;p&gt;不過我的話，還是 vim 無敵呀。Navigation 用 gf 可以直接跳來跳去，Find Usage 可以用 grep -r --color Patern dir 來取代， 取出 db schema 可以直接用 mysql client + explain db schema 來做到。鍵盤還是真正的王道。&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4651239897265249160?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/4651239897265249160/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=4651239897265249160' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4651239897265249160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4651239897265249160'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/03/netbeans-6.html' title='Netbeans 6 相當的威'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3296/2334510284_58f6572262_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-7915020354689441439</id><published>2008-03-09T19:18:00.005+08:00</published><updated>2008-03-09T19:59:13.323+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='juggenaut'/><title type='text'>Rails PUSH Server ：Juggernaut 簡介</title><content type='html'>早就想寫 Juggernaut 的文章了，不過今天是第一次有時間寫。Push Server 技術就不再提了，想知道可以看我之前寫的文章。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;簡介&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Juggernaut 簡單的來說，是一個 Ruby Push Server 加上 Rails Plugin。&lt;br /&gt;&lt;br /&gt;Push Server 取名就叫作 Juggernaut。&lt;br /&gt;&lt;br /&gt;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 整合良好，我們來看看怎麼使用。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;安裝&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. Push Server 安裝&lt;br /&gt;&lt;br /&gt;gem i juggernaut -y&lt;br /&gt;&lt;br /&gt;2. Rails Plugin 安裝&lt;br /&gt;&lt;br /&gt;ruby script/plugin install http://juggernaut.rubyforge.org/svn/trunk/juggernaut&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;設定&lt;br /&gt;&lt;br /&gt;1. Juggernaut_hosts.yml&lt;br /&gt;&lt;br /&gt;這裡很容易混淆，這個設定檔是 Rails Plugin 要看的設定檔，如果沒有設定 config/juggernaut_hosts.yml，會導致 Rails 無法啟動，所以必須要設定 config/juggernaut_hosts.yml。請先新增一個 config/juggernaut_hosts.yml ，輸入你的 Push Server 環境&lt;br /&gt;&lt;br /&gt;:hosts:&lt;br /&gt;- :port: 5001&lt;br /&gt;:host: localhost&lt;br /&gt;:environment: :production&lt;br /&gt;&lt;br /&gt;port 是 push server port ，預設是 5001，Host 是 Push Server 的 IP ，Enviroment 是 Rails 環境。&lt;br /&gt;&lt;br /&gt;2. juggernaut.yml&lt;br /&gt;&lt;br /&gt;我們用 juggernaut 來產生 juggernaut push server 所需的設定檔。以下指令會產生一個 juggernaut config 檔，取名叫作 juggernaut.yml。&lt;br /&gt;&lt;br /&gt;juggernaut -g juggernaut.yml&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;啟動&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;要啟動就是要啟動 Push Server ，還有 Ruby on Rails 。&lt;br /&gt;1. 啟動 push server&lt;br /&gt;我們啟動 juggernaut 這個 push server，並且讀取 config 檔。 預設 Push Server port 是 5001，可以到 juggernaut.yml 去修改。&lt;br /&gt;juggernaut -c juggernaut.yml&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;範例&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;我們直接用 juggernaut 的範例，聊天室來確認是否 ok。在你的 controller 裡面創立兩個 function&lt;br /&gt;&lt;pre&gt;&lt;strong&gt;def&lt;span style="color: rgb(255, 0, 0);"&gt; index&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;def&lt;span style="color: rgb(255, 0, 0);"&gt; send_data&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;render &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;juggernaut &lt;strong&gt;do&lt;/strong&gt; |page|&lt;br /&gt;page.insert_html &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;top&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'chat_data'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"&lt;li&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;#{h params[:chat_input]}&lt;/span&gt;&lt;/li&gt;"&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;render &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;nothing &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; &lt;strong&gt;true&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/pre&gt;然後在 index view 裡面這樣寫&lt;br /&gt;&lt;pre&gt;&lt;span style="color:#4444ff;"&gt;&lt;&lt;/span&gt;html&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="color:#4444ff;"&gt;&lt;&lt;/span&gt;head&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#4444ff;"&gt;&lt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;%= javascript_include_tag :defaults, :juggernaut %&gt;&lt;br /&gt;   &lt;%=&lt;/span&gt; juggernaut %&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="color:#4444ff;"&gt;&lt;/&lt;/span&gt;head&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="color:#4444ff;"&gt;&lt;&lt;/span&gt;body&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#4444ff;"&gt;&lt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;%= form_remote_tag( :url =&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt; &lt;span style="color:#4444ff;"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; &lt;span style="color:#4444ff;"&gt;:&lt;/span&gt;action &lt;span style="color:#4444ff;"&gt;=&gt;&lt;/span&gt; &lt;span style="color:#4444ff;"&gt;:&lt;/span&gt;send_data &lt;span style="color:#4444ff;"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;,&lt;/span&gt; &lt;span style="color:#4444ff;"&gt;:&lt;/span&gt;complete &lt;span style="color:#4444ff;"&gt;=&gt;&lt;/span&gt; &lt;span style="color:#008000;"&gt;"$('chat_input').value = ''"&lt;/span&gt; &lt;span style="color:#4444ff;"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt; %&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#4444ff;"&gt;&lt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;%= text_field_tag( 'chat_input', '', { :size =&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;20&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;,&lt;/span&gt; &lt;span style="color:#4444ff;"&gt;:&lt;/span&gt;id &lt;span style="color:#4444ff;"&gt;=&gt;&lt;/span&gt; &lt;span style="color:#008000;"&gt;'chat_input'&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt; &lt;span style="color:#4444ff;"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt; %&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#4444ff;"&gt;&lt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;%= submit_tag "Add" %&gt;&lt;br /&gt; &lt; /form&gt;&lt;br /&gt; &lt; id="&lt;/font"&gt;&lt;span style="color:#008000;"&gt;"chat_data"&lt;/span&gt; style&lt;span style="color:#4444ff;"&gt;=&lt;/span&gt;&lt;span style="color:#008000;"&gt;"list-style:none"&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt; &lt;span style="color:#4444ff;"&gt;&lt;/&lt;/span&gt;ul&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#4444ff;"&gt;&lt;/&lt;/span&gt;body&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#4444ff;"&gt;&lt;/&lt;/span&gt;html&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;這樣聊天室就完成啦，可以試試看玩玩看。&lt;br /&gt;&lt;br /&gt;對了，這個聊天室一開始有一堆 alert message，這是 Juggernaut 預設 Development 環境下會啟動 Debug Function ，只要 config 改成 Production 就不會出現一堆 alert message。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7915020354689441439?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/7915020354689441439/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=7915020354689441439' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7915020354689441439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7915020354689441439'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/03/rails-push-server-juggernaut.html' title='Rails PUSH Server ：Juggernaut 簡介'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-1632665277620878797</id><published>2008-03-05T12:10:00.001+08:00</published><updated>2008-03-05T12:10:37.526+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='appserver'/><title type='text'>Ebb：又來一個的 Application Server</title><content type='html'>&lt;p&gt;這年頭發展 Application Server 好像很有搞頭，也或許是 Rails 社群對 &lt;a href="http://lightyror.thegiive.net/2008/01/rails-is-ghetto.html"&gt;Zed Shaw 的高調離去&lt;/a&gt;的反撲。總之，2008 年一月出了 Thin，二月出了&lt;span style="font-family: Arial; font-size: 14px; line-height: 25px;"&gt;&lt;a href="http://switchpipe.org/" target="_blank" style="color: #006699; text-decoration: underline;"&gt;SwitchPipe&lt;/a&gt;和&lt;a href="http://swiftiply.swiftcore.org/" target="_blank" style="color: #006699; text-decoration: underline;"&gt;Swiftiply&lt;/a&gt;&lt;span style="font-family: Helvetica; font-size: 12px; line-height: normal;"&gt;，現在又有一個 Rails App Server &lt;a href="http://ebb.rubyforge.org/"&gt;Ebb&lt;/a&gt; 出了，而且好像真的很有料。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://farm4.static.flickr.com/3157/2311855018_e455b8c35c_o.jpg" width="400" height="300" alt="ebb-concurrency.jpg" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;上面這張圖是 ebb 跟 Mongrel ，和 Event-Driven Mongrel，Thin 的負載程度 benckmark。我們可以發現 ebb 跟其他的 Rails App Server 根本就是不同等級的負載程度。他的 Design 架構上面比較像 Event-Driven Mongrel，差別比較大的就是他很多地方用 c 寫成。&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;安裝方式&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;gem i ebb&lt;/p&gt;&lt;br /&gt;&lt;p&gt;記得先安裝 glib2。&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;跑的方式&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;ebb_rails start&lt;/p&gt;&lt;br /&gt;&lt;p&gt;很熟悉的指令。&lt;/p&gt;&lt;br /&gt;&lt;p&gt;測試一下好了。&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1632665277620878797?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/1632665277620878797/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=1632665277620878797' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1632665277620878797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1632665277620878797'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/03/ebb-application-server.html' title='Ebb：又來一個的 Application Server'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-6798575745592059440</id><published>2008-02-28T09:37:00.000+08:00</published><updated>2008-02-28T11:36:05.628+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='case'/><title type='text'>Friends for Sale ：一天一千萬 Page View 的 Rails Service</title><content type='html'>&lt;p&gt;&lt;img src="http://farm4.static.flickr.com/3035/2296646701_e917be1c63_t.jpg" width="186" height="139" alt="app_3_7019261521_7189.gif" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://www.facebook.com/apps/application.php?id=7019261521"&gt;Friends for Sale&lt;/a&gt; 是一個在 FaceBook 上面排行前十的 Facebook App，最近他公佈他的&lt;a href="http://highscalability.com/friends-sale-architecture-300-million-page-view-month-facebook-ror-app"&gt;資料&lt;/a&gt;，他是 Ruby on Rails 寫的。他上面有 60萬個會員，一個月 3億個 PV，並且以每個月 300%繼續成長。上個月流量是 3T，不過大部份都是圖片的支出。&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;架構是標準的 Rails Cluster，Front end 是 Nginx，Application Server 是 Mongrel。&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;他們學到課程如下&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;  &lt;li&gt;如果在Facebook 上面開發 APP，一開始就要想到 Scaling Problem（四周就衝到 1 m pv/day）&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;&lt;strong&gt;Ruby on Rails can scale&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;&lt;strong&gt;&lt;span style="font-weight: normal;"&gt;Performance Problem 是在 DB，你需要有很好的 DBA&lt;/span&gt;&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;&lt;strong&gt;&lt;span style="font-weight: normal;"&gt;Cache 用的好，DB 不嫌少&lt;/span&gt;&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;他們使用&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;  &lt;li&gt;Ruby on Rails&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;CentOS 5&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Memcached&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;MySQL 5.1&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Nginx&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Starling( Distribute Queue Server）&lt;span style="color: #494949; font-family: Verdana; line-height: 20px;"&gt;&lt;a href="http://magicmodels.rubyforge.org/magic_multi_connections/" style="color: #6C420E; text-decoration: none;"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;&lt;span style="color: #494949; font-family: Verdana; line-height: 20px;"&gt;&lt;a href="http://magicmodels.rubyforge.org/magic_multi_connections/" style="color: #6C420E; text-decoration: none;"&gt;Dr. Nics Magic Multi-Connections Gem&lt;/a&gt; ( Read Write 不同個 DB）&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;使用硬體&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;  &lt;li&gt;6台 4 core 的 App Server，每台 16 Mongrel Instance，並且每台都放 4GB Memcached 。&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;4台 DB Server，上面配備 32GB 4 core servers with 4x 15K SCSI RAID 10 disks，使用 Master-Slave，用 Multi-Connection Gem 來達成 Read Write 不同 DB。&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;1 Starling Server&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;1 frontend server&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;  &lt;li style="list-style: none"&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6798575745592059440?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/6798575745592059440/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=6798575745592059440' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6798575745592059440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6798575745592059440'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/02/friends-for-sale-page-view-rails.html' title='Friends for Sale ：一天一千萬 Page View 的 Rails Service'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3035/2296646701_e917be1c63_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-1274425280561990031</id><published>2008-02-28T09:04:00.001+08:00</published><updated>2008-02-28T09:04:53.425+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vm'/><title type='text'>Adobe 計畫擴展Flash 支援其他語言</title><content type='html'>&lt;p&gt;從 &lt;a href="http://www.javaeye.com/news/1305"&gt;JavaEye 看到的東西&lt;/a&gt;， &lt;span style="font-family: Arial; font-size: 14px; line-height: 25px;"&gt;Adobe CTO Kevin Lynch在 Adobe Engage 上面講說，他們預計將其他 language 帶入 Flash ，使得 Flash 不只是可以用 ActionScript，還可以使用其他的 Language。最後也只是將 Language Compile成 Flash 的 swf Bytecode。&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;感覺又是一個 VM 的即將誕生。&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1274425280561990031?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/1274425280561990031/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=1274425280561990031' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1274425280561990031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1274425280561990031'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/02/adobe-flash.html' title='Adobe 計畫擴展Flash 支援其他語言'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-4231899319155711022</id><published>2008-02-19T23:31:00.003+08:00</published><updated>2008-02-19T23:39:05.118+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby_binding'/><title type='text'>Rice - Ruby Interface for C++ Extensions</title><content type='html'>Rice - Ruby Interface for C++ Extensions&lt;br /&gt;&lt;br /&gt;一年半前（天啊，有這麼早嗎？）曾經介紹過 swig, 一個專門產生各種介於 C/C++ 與其他語言 interface 的產生器。他是利用一個自訂的表示法，藉由讀取該表示法，產生出各種不同真正的 binding 程式。其中也有內建不少 STL 的 binding,所以想用 STL 的東西並不見得需要自己寫，只要叫他內部的東西出來即可。&lt;br /&gt;&lt;br /&gt;swig 很厲害，不過他有個麻煩。雖然說 DSL 的威力強大，但是對於想要快速上手而言，其實有時候反而會是種阻礙。另一方面，我 swig 手冊翻了翻，要把 C++ port 到 ruby 很容易，但反之不亦然，要在 C++ 中使用 ruby object, 就不是那麼方便。（雖然也許這樣做是奇怪了點...）&lt;br /&gt;&lt;br /&gt;所以後來我試了 Rice.&lt;br /&gt;http://rice.rubyforge.org/&lt;br /&gt;rice 的官方手冊也說了，rice 並不是要來取代 swig 的。swig 有他的不足，而 rice 大抵上又是模仿 boost.python 而作成的，所以兩者並不同。他自己也做過不少東西是同時使用 swig 和 rice. 不過也不能說 rice 是 ruby 版的 boost.python. 因為他的目的也不是完全模仿 boost.python.&lt;br /&gt;&lt;br /&gt;anyway, 之所以會想試用，是出自於找不太到良好的 C++ yaml parser. 我有看到兩個 C 版本的實作，但是真不好意思啊，個人實在不太喜歡純 C 的東西...。所以想說如果可以把 ruby 的 yaml 搬過來就太好了。以下就是測試結果：&lt;br /&gt;&lt;br /&gt;&gt; sudo gem install rice&lt;br /&gt;&lt;br /&gt;理論上這樣安裝是最方便的。要在 C++ 裡執行 ruby, 一樣會需要 ruby.h. 一般來說，他會在 lib/ruby/1.8/your_architecture/ 裡面。在我的電腦上，他是：/opt/local/lib/ruby/1.8/i686-darwin9.1.0/&lt;br /&gt;&lt;br /&gt;而 rice 呢，則是在 lib/ruby/gems/1.8/gems/rice-x.y.z/, librice.a 則是在 lib/ruby/gems/1.8/gems/rice-x.y.z/rice/ 下。&lt;br /&gt;&lt;br /&gt;所以在我的電腦裡，g++ options 是這樣下：&lt;br /&gt;&lt;br /&gt;-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&lt;br /&gt;&lt;br /&gt;主程式大概是長這樣：&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;int main(){&lt;br /&gt;    using Rice::Hash;&lt;br /&gt;    using Rice::protect;&lt;br /&gt;&lt;br /&gt;    ruby_init(); // 使用 ruby 前一定要呼叫&lt;br /&gt;    // 設定 load path, 否則 load path 會是 []&lt;br /&gt;    rb_eval_string("$LOAD_PATH &amp;lt;&amp;lt; '/opt/local/lib/ruby/1.8'");&lt;br /&gt;    rb_eval_string("$LOAD_PATH &amp;lt;&amp;lt; '/opt/local/lib/ruby/1.8/i686-darwin9.1.0'");&lt;br /&gt;&lt;br /&gt;    // require yaml 進來。當然也可以用上面的方式 require. 不過之所以會這樣寫，&lt;br /&gt;    // 是因為我不知道 load path 要怎麼直接從 rb_ function 中設定？&lt;br /&gt;    // 否則我是覺得能用 rb_ 去跑盡量用，evil eval 不是叫假的...&lt;br /&gt;    rb_require("yaml");&lt;br /&gt;&lt;br /&gt;    // protect 我猜是把所有的錯誤都轉成 rice 本身的 exception.&lt;br /&gt;    // Hash, 則是 ruby 的 hash 在 C++ 裡的 wrapper,&lt;br /&gt;    // 所以我是把 YAML 的讀取結果存入這份 C++ Hash 中。&lt;br /&gt;    Hash h(protect(rb_eval_string, "YAML.load(File.read('database.yml'))"));&lt;br /&gt;&lt;br /&gt;    // 這邊，我要做的事只是展現如何使用這份 hash.&lt;br /&gt;    Extractor e;&lt;br /&gt;    e.extract(h);&lt;br /&gt;    std::cout &amp;lt;&amp;lt; std::endl;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;雖然我覺得 doxygen 生出來的東西常常很難閱讀，不過 rice 的 doxygen 文件還算不錯，有什麼東西都很清楚。就算不夠清楚，也能去直接看他的原始檔。他原始檔的東西並不多，稍微翻一下，有什麼疑惑我想都可以解決。根據我 C++ 的經驗，rice 這份程式也算是寫得非常漂亮的了，應該滿有參考價值。&lt;br /&gt;&lt;br /&gt;我的 extractor 是把整個 hash 都走過一次，如果不需要這麼複雜的操作，其實也可以很單純地這樣呼叫：&lt;br /&gt;&lt;br /&gt;std::cout &amp;lt;&amp;lt; static_cast&amp;lt;Hash&amp;gt;(h[String("development")])[String("adapter")];&lt;br /&gt;&lt;br /&gt;這樣會輸出：&lt;br /&gt;&lt;br /&gt;sqlite1&lt;br /&gt;&lt;br /&gt;這樣實在是有點囉唆沒錯，不過我想這可以靠擴充 rice 解決。他有個 from_ruby 和 to_ruby 的 template, 擴充那個東西，好像就能把很多東西從 explicit 法轉成 implicit 法。不過我暫時懶得去做那麼多研究，這應該都是小問題。不過 down cast 就比較麻煩了。他有個 get method, 好像是能做一些 down cast, 但我測試都會有 runtime error, 大概是用法不對吧。有興趣的人歡迎去研究看看要怎麼做。&lt;br /&gt;&lt;br /&gt;extractor 我想就不解釋了，就只是單純把抓出的 yaml 再輸出回 yaml. 其實那都已經差不多單純是 C++ 的問題了。僅列出程式碼與附註的一些註解：（不過我沒測試過比較複雜的 yaml, 我想一定會有問題，當作業自己試著改好吧 :p）&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#include &amp;lt;ruby.h&amp;gt;&lt;br /&gt;#include &amp;lt;rice/Hash.hpp&amp;gt;&lt;br /&gt;#include &amp;lt;rice/Array.hpp&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;using Rice::Object;&lt;br /&gt;using Rice::Class;&lt;br /&gt;using Rice::Hash;&lt;br /&gt;using Rice::Array;&lt;br /&gt;using Rice::String;&lt;br /&gt;&lt;br /&gt;// 排版算空格用的&lt;br /&gt;std::string spacer(int depth){&lt;br /&gt;    std::string result;&lt;br /&gt;    for(int i=0; i&amp;lt;depth; ++i)&lt;br /&gt;        result += "  ";&lt;br /&gt;    return result;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Extractor{&lt;br /&gt;public:&lt;br /&gt;    // 他 class 判斷法有點麻煩，所以我先把這三個 class instance cache 起來&lt;br /&gt;    Extractor(): hash_class_(Hash().class_of()),&lt;br /&gt;                 array_class_(Array().class_of()),&lt;br /&gt;                 string_class_(String().class_of())&lt;br /&gt;    {}&lt;br /&gt;    void extract(Object const&amp; obj, int depth = 0) const{&lt;br /&gt;        if(obj.is_instance_of(hash_class_))&lt;br /&gt;            extract_hash(obj, depth);&lt;br /&gt;        else if(obj.is_instance_of(array_class_))&lt;br /&gt;            extract_array(obj, depth);&lt;br /&gt;        else if(obj.is_instance_of(string_class_))&lt;br /&gt;            std::cout &amp;lt;&amp;lt; spacer(depth) &amp;lt;&amp;lt; obj &amp;lt;&amp;lt; "\n";&lt;br /&gt;        else // 這表示他是 Fixnum or Float?&lt;br /&gt;            std::cout &amp;lt;&amp;lt; spacer(depth) &amp;lt;&amp;lt; obj &amp;lt;&amp;lt; "\n";&lt;br /&gt;    }&lt;br /&gt;private:&lt;br /&gt;    void extract_array(Array const&amp; obj, int depth) const{&lt;br /&gt;        for(Array::const_iterator i=obj.begin(), iend=obj.end(); i!=iend; ++i)&lt;br /&gt;            extract(*i, depth);&lt;br /&gt;    }&lt;br /&gt;    void extract_hash(Hash const&amp; obj, int depth) const{&lt;br /&gt;        for(Hash::const_iterator i=obj.begin(), iend=obj.end(); i!=iend; ++i){&lt;br /&gt;            std::cout &amp;lt;&amp;lt; spacer(depth) &amp;lt;&amp;lt; i-&gt;key &amp;lt;&amp;lt; ":";&lt;br /&gt;&lt;br /&gt;        // i-&gt;value 結果會是 ruby 上 C 的 VALUE, 所以要 cast 成 Rice::Object&lt;br /&gt;            if(static_cast&amp;lt;Object&amp;gt;(i-&gt;value).is_instance_of(hash_class_))&lt;br /&gt;                std::cout &amp;lt;&amp;lt; "\n", extract(i-&gt;value, depth+1);&lt;br /&gt;            else // 單純的值&lt;br /&gt;                std::cout &amp;lt;&amp;lt; " ", extract(i-&gt;value, 0);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;private:&lt;br /&gt;    Class hash_class_, array_class_, string_class_;&lt;br /&gt;};&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4231899319155711022?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/4231899319155711022/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=4231899319155711022' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4231899319155711022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4231899319155711022'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/02/rice-ruby-interface-for-c-extensions.html' title='Rice - Ruby Interface for C++ Extensions'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-8396494359370571961</id><published>2008-02-03T14:55:00.000+08:00</published><updated>2008-02-03T15:11:46.180+08:00</updated><title type='text'>Twitter 正式離開 Joyent</title><content type='html'>從&lt;a href="http://blog.gslin.org/archives/2008/02/02/1418/"&gt;大神&lt;/a&gt;那看到的消息。Twitter 之前選擇 &lt;a href="http://www.joyent.com/"&gt;Joyent&lt;/a&gt; 作為自己的 Hosting Service ，不過為了提供更穩定的服務，他們決定移轉到 &lt;a href="http://www.nttamerica.com/products/hosting/index.php"&gt;NTT American &lt;/a&gt;這家公司。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8396494359370571961?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/8396494359370571961/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=8396494359370571961' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8396494359370571961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8396494359370571961'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/02/twitter-joyent.html' title='Twitter 正式離開 Joyent'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-2114361722269023846</id><published>2008-01-22T10:19:00.000+08:00</published><updated>2008-01-22T10:36:37.164+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='talk'/><title type='text'>微軟即將把IE6強制升級至 IE7</title><content type='html'>從&lt;a href="http://blog.gslin.org/archives/2008/01/22/1411/"&gt;大神&lt;/a&gt;那看到的，微軟將作一件功德無量的好事，他們即將在今年二月十二號，利用 Windwos Server Update Service 將系統裡面的 IE6 改成 IE7。&lt;br /&gt;&lt;br /&gt;相信此一升級對於 IE6 only 網站來說是一個大震撼，恐怕也會有大幅度的網頁改版潮。但是對於任何一個網頁程式設計師，或是網頁美工來說，都是一個放鞭炮的消息。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-2114361722269023846?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/2114361722269023846/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=2114361722269023846' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2114361722269023846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2114361722269023846'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/01/ie6-ie7.html' title='微軟即將把IE6強制升級至 IE7'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-6072792304000695306</id><published>2008-01-17T21:52:00.000+08:00</published><updated>2008-01-18T10:00:09.520+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thin'/><title type='text'>Thin ：有可能超越 Mongrel 的 App Server</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;介紹&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_8vS0KjIsbko/R49fWbbJHdI/AAAAAAAAANI/H5q9KkuDAUs/s1600-h/logo.gif"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp3.blogger.com/_8vS0KjIsbko/R49fWbbJHdI/AAAAAAAAANI/H5q9KkuDAUs/s320/logo.gif" alt="" id="BLOGGER_PHOTO_ID_5156444937285869010" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;在Zed Shaw 離開了 Mongrel 之後，每個使用者人心惶惶，不知道 Rails 的 App Server 會不會出大問題。這時候，彷彿在跟 Zed 說「Rails 社群不會被打敗」，&lt;a href="http://code.macournoyer.com/thin/"&gt;Thin &lt;/a&gt;出現了。&lt;br /&gt;&lt;br /&gt;Thin 是一個 Mashup App Server ，採用了作者認為 Ruby 當中數一數二好的 Lib&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Mongrel Parser：Mongrel 速度跟安全性的根本&lt;/li&gt;&lt;li&gt;Events Machine：快速，穩定的 Network IO Lib&lt;/li&gt;&lt;li&gt;Rack：Webserver 跟 Ruby 之間的 Interface&lt;/li&gt;&lt;/ul&gt;這幾個強大的 Lib，整合在一起分工合作，讓 Thin 成為安全，穩定，快速，好擴充的 Web Server。&lt;br /&gt;&lt;br /&gt;當然，快速是他第一個優點。在他的測試中， Thin 超越了 Mongrel 跟 Event-Driven Mongrel。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_8vS0KjIsbko/R49hKrbJHeI/AAAAAAAAANQ/SM68WX-qkl4/s1600-h/chart.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_8vS0KjIsbko/R49hKrbJHeI/AAAAAAAAANQ/SM68WX-qkl4/s320/chart.png" alt="" id="BLOGGER_PHOTO_ID_5156446934445661666" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.javaeye.com/topic/153381"&gt;JavaEye 網友的測試&lt;/a&gt;也發現，不論是 Ruby 1.8 ，Ruby 1.9，Thin 的速度也是超越 Mongrel 。Ruby 1.9 裡面 req/s 居然是 4154 : 1313 的可怕差距&lt;br /&gt;&lt;blockquote&gt;Mongrel    1000      100               1313.19   0&lt;br /&gt;Thin          1000      100               4154.67   0&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;安裝方式&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;用 gem 安裝即可&lt;br /&gt;&lt;blockquote&gt;gem i thin &lt;/blockquote&gt;要執行 thin ，就是在 Rails 的根目錄下執行&lt;br /&gt;&lt;blockquote&gt;thin start &lt;/blockquote&gt;可惜沒有 Cluster 版本，不過，對岸網友已經寫了一個&lt;a href="http://www.ruby-lang.org.cn/forums/redirect.php?tid=2835&amp;amp;goto=lastpost"&gt;應急的 rake file&lt;/a&gt;，只可惜沒有指定 Port 的 command，所以我稍微修改一下成為這樣&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;namespace &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;thin &lt;strong&gt;do&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;namespace &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;cluster &lt;strong&gt;do&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;desc &lt;span style="color: rgb(0, 128, 0);"&gt;'Start thin cluster'&lt;/span&gt;&lt;br /&gt;task &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;start &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;environment &lt;strong&gt;do&lt;/strong&gt;&lt;br /&gt;`cd &lt;span style="color: rgb(68, 68, 68);"&gt;#{RAILS_ROOT}`&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt;ENV&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;'SIZE'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt; ? &lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt;ENV&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;'SIZE'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;.to_i &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;4&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;.times &lt;strong&gt;do&lt;/strong&gt; |i|&lt;br /&gt;Thread.new &lt;strong&gt;do&lt;/strong&gt;&lt;br /&gt;port &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt;ENV&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;'PORT'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;.to_i + 1&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;str &lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"thin start -d -p&lt;span style="color: rgb(32, 64, 160);"&gt;#{port}&lt;/span&gt; -Ptmp/pids/thin-&lt;span style="color: rgb(32, 64, 160);"&gt;#{port}&lt;/span&gt;.pid"&lt;/span&gt;&lt;br /&gt;str &lt;span style="color: rgb(68, 68, 255);"&gt;+=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;" -e&lt;span style="color: rgb(32, 64, 160);"&gt;#{RAILS_ENV}&lt;/span&gt;"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;puts&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"Starting server on port &lt;span style="color: rgb(32, 64, 160);"&gt;#{port}&lt;/span&gt;..."&lt;/span&gt;&lt;br /&gt;`&lt;span style="color: rgb(68, 68, 68);"&gt;#{str}`&lt;br /&gt;&lt;/span&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;desc &lt;span style="color: rgb(0, 128, 0);"&gt;'Stop thin cluster'&lt;/span&gt;&lt;br /&gt;task &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;stop &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;environment &lt;strong&gt;do&lt;/strong&gt;&lt;br /&gt;`cd &lt;span style="color: rgb(68, 68, 68);"&gt;#{RAILS_ROOT}`&lt;br /&gt;&lt;/span&gt;Dir.new&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;"&lt;span style="color: rgb(32, 64, 160);"&gt;#{RAILS_ROOT}&lt;/span&gt;/tmp/pids"&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;.each &lt;strong&gt;do&lt;/strong&gt; |file|&lt;br /&gt;Thread.new &lt;strong&gt;do&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;if&lt;/strong&gt; file.starts_with?&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;"thin-&lt;span style="color: rgb(32, 64, 160);"&gt;#{port_range}&lt;/span&gt;"&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;str &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"thin stop -Ptmp/pids/&lt;span style="color: rgb(32, 64, 160);"&gt;#{file}&lt;/span&gt;"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;puts&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"Stopping server on port &lt;span style="color: rgb(32, 64, 160);"&gt;#{file[/\d+/]}&lt;/span&gt;..."&lt;/span&gt;&lt;br /&gt;`&lt;span style="color: rgb(68, 68, 68);"&gt;#{str}`&lt;br /&gt;&lt;/span&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/blockquote&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/pre&gt;將這個東西貼在 Rails 根目錄的 Rakefile ，將它貼在最後面，然後執行下面指令啟動&lt;br /&gt;&lt;blockquote&gt;rake thin:cluster:start RAILS_ENV=&lt;span style="color: rgb(153, 153, 153);"&gt;production&lt;/span&gt; SIZE=&lt;span style="color: rgb(153, 153, 153);"&gt;10&lt;/span&gt; PORT=&lt;span style="color: rgb(153, 153, 153);"&gt;4000&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="color: rgb(153, 153, 153);"&gt;&lt;/span&gt;灰色的代表可以自己填寫的選項，包含 Rails 啟動的 enviroment，執行幾個 thin ，還有從哪個 Port 開始 listen。有用過 mongrel_cluster 應該都很清楚。停止就是&lt;br /&gt;&lt;blockquote&gt;rake thin:cluster:stop&lt;/blockquote&gt;他會砍掉 tmp/pids/thin- 開頭的 pid file。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6072792304000695306?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/6072792304000695306/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=6072792304000695306' title='5 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6072792304000695306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6072792304000695306'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/01/thin-mongrel-app-server.html' title='Thin ：有可能超越 Mongrel 的 App Server'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_8vS0KjIsbko/R49fWbbJHdI/AAAAAAAAANI/H5q9KkuDAUs/s72-c/logo.gif' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-3855391849319605052</id><published>2008-01-17T11:20:00.000+08:00</published><updated>2008-01-17T14:04:03.941+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='news'/><title type='text'>Sun 買下 MySQL</title><content type='html'>今早看到的新聞，還蠻震撼的，&lt;a href="http://www.sun.com/aboutsun/pr/2008-01/sunflash.20080116.1.xml"&gt;Sun 買下 MySQL&lt;/a&gt;。此舉讓 Sun 成為 Open Source 廠商中數一數二的領導地位。BTW，nobody knows it will be good or bad.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-3855391849319605052?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/3855391849319605052/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=3855391849319605052' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3855391849319605052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3855391849319605052'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/01/sun-mysql.html' title='Sun 買下 MySQL'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-2064595057711558800</id><published>2008-01-10T11:08:00.000+08:00</published><updated>2008-01-11T00:19:28.366+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><title type='text'>JRuby 1.1 RC1 Release</title><content type='html'>&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;本文&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://docs.codehaus.org/display/JRUBY/2008/01/08/The+JRuby+community+is+pleased+to+announce+the+release+of+JRuby+1.1+RC+1"&gt;JRuby 1.1 RC1 Release!!!&lt;/a&gt;。&lt;/span&gt;正如之前所看到的消息，JRuby 1.1 跟 JRuby 1.0 最大的改進就是在 Performance 的不同，速度上比起 1.0.2 約有 &lt;a href="http://on-ruby.blogspot.com/2008/01/jruby-11rc1-real-world-performance.html"&gt;27% 的改善&lt;/a&gt;，主要的改進有兩個&lt;br /&gt;&lt;br /&gt;1. JRuby 可以用  Ahead Of Time (AOT) 或是 Just In Time (JIT) 兩種模式進行 compile。&lt;br /&gt;2. JRuby 使用 Oniguruma 的 JRuby porting Juni，當作 Regular Expression 的 Engine。&lt;br /&gt;&lt;br /&gt;總之，恭喜 JRuby Team。&lt;br /&gt;&lt;br /&gt;下載：http://dist.codehaus.org/jruby/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;本文結束後的講古，爆米花請準備好&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;說到 JRuby 的 regular expression ，可有說不完的故事（可以看 &lt;a href="http://www.infoq.com/cn/news/2007/12/oniguruma-joni-jruby"&gt;InfoQ版本&lt;/a&gt;）。&lt;br /&gt;&lt;br /&gt;早期 JRuby 原本使用 Java 1.4 以後內建的 regex ，雖然很簡單，但是以一個目標是 Ruby 1.8 compatiable 的 project 來說，Java 內建的 regex 不合用。為了解決這個問題， JRuby Team 改採用 &lt;a href="http://jregex.sourceforge.net/"&gt;JRegex&lt;/a&gt;  ，並且也納入了 JRuby 1.0 裡面。&lt;br /&gt;&lt;br /&gt;但是 &lt;a href="http://jregex.sourceforge.net/"&gt;JRegex&lt;/a&gt; 某些細節跟 Ruby Regex 不太類似，依舊傷害了JRuby 對於 MRI Ruby 的兼容性 ，而且  &lt;a href="http://jregex.sourceforge.net/"&gt;JRegex&lt;/a&gt; 以 Java 的程式來說，已經算很快了，但是依舊不夠快速。 JRuby Team 在&lt;a href="http://ola-bini.blogspot.com/2007/10/jruby-discovery-number-one.html"&gt;測試&lt;/a&gt;JRuby 跑 Rails 的時候，他們發現 regular expression 成為顯著的 Bottleneck。&lt;br /&gt;&lt;blockquote&gt;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.&lt;br /&gt;&lt;/blockquote&gt;所以他們決定使用更快的 Regular Expression Engine 來徹底解決 JRuby on Rails 的效能問題。他們選中了 &lt;a href="http://www.geocities.jp/kosako3/oniguruma/"&gt;Oniguruma&lt;/a&gt; 這個 Ruby 的 regular expression Engine，這是 Ruby 1.9 內建的新 Regular Expression Engine。&lt;br /&gt;&lt;br /&gt;Oniguruma 看來難念，其實是日本字，意思是鬼車，不過比起鬼車，我比較喜歡&lt;a href="http://chinaonrails.com/topic/view/609.html"&gt;對岸&lt;/a&gt;的講法 XD&lt;br /&gt;&lt;blockquote&gt;O ni guru ma&lt;br /&gt;哦 , 你 咕噜 吗？&lt;/blockquote&gt;真的好記很多。Oniguruma 支援多個 charset 的 regular expression，已經是一個成熟的 regular expression engine。所以 JRuby Team 選擇了 Oniguruma 當作新的目標，將他 Porting 成 JRuby 版本，並且將他改名為 Juni。後來發現 Juni 相對於 JRegex ，的確對於 JRuby 帶來了&lt;a href="http://headius.blogspot.com/2007/11/rexml-numbers-with-joni.html"&gt;顯著的效能上升&lt;/a&gt;。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-2064595057711558800?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/2064595057711558800/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=2064595057711558800' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2064595057711558800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2064595057711558800'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/01/jruby-11-rc1-release.html' title='JRuby 1.1 RC1 Release'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-6694571877222626605</id><published>2008-01-08T13:43:00.000+08:00</published><updated>2008-01-08T15:23:48.816+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='talk'/><title type='text'>Ruby 跟  Python 本質上不同</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;前言&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;對岸高手孟岩最近寫了一篇「&lt;a href="http://blog.csdn.net/myan/archive/2008/01/07/2028545.aspx"&gt;Ruby 1.9不会杀死Python&lt;/a&gt;」，裡面提到 Ruby 1.9 一出，彷彿 Ruby 已經邁向完全體，所有的缺點都已經消失了。彷彿已經要一統武林&lt;br /&gt;&lt;blockquote&gt;有人认为，这下子不得了了，Ruby要称霸动态语言了。你想想，Ruby已经几乎拥有了所有梦幻般的语言特性，神奇的动态能力，强大的支持库，内置的跟Perl可以比肩的正则表达式，Smalltalk级别的纯而又纯的面向对象特征，简洁明快的风格，跨语言整合也非常容易，唯一的缺点就是速度慢。现在连这个缺点都被弥补了，Ruby还能挡得住吗？其他的动态语言都该歇菜了。&lt;br /&gt;&lt;/blockquote&gt;然後他又提到一個很有趣的分類，Ruby 是魔幻語言，Python 是簡約語言。Robbin 老大也出來講了&lt;a href="http://robbin.javaeye.com/blog/153749"&gt;Ruby为什么会受程序员的欢迎？&lt;/a&gt;。一整篇看下來，實在是很過癮。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;簡約語言&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;簡約語言是什麼呢？大致上是 C、PHP、Python和Lua，C# ，Java。他的大概意含可以由Python 的中心思想 EIBTI 可以略知一二&lt;br /&gt;&lt;blockquote&gt;Explicit is better than implicit.&lt;/blockquote&gt;看不懂的話，用更白話的方式來解釋，The Zen of Python 裡面有提到&lt;br /&gt;&lt;blockquote&gt;There should be one-- and preferably only one --obvious way to do it.&lt;/blockquote&gt;也就是，Python  有意的限制語言的表示方式，使得不好的 coding 習慣都不能 Compile 過，有意的強制使用者養成良好的習慣。&lt;br /&gt;&lt;br /&gt;這雖然極端了點，但也不超乎其他簡約語言的中心思想。簡約語言不關心語言的表述方式，他們在乎的是「解決問題」。以工程來看，簡約語言在大專案裡面的協同工作上面較為吃香。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;魔幻語言&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;我很喜歡這個詞。魔幻語言的代表有 C++、Perl、Javascript和Ruby。中心思想可以由 Perl 的 TMTOWTDI 來表示&lt;br /&gt;&lt;blockquote&gt;There's More Than One Way To Do It.&lt;/blockquote&gt;魔幻語言的擁護者思考的東西，這位孟岩老大也描寫的很傳神&lt;br /&gt;&lt;blockquote&gt;他们写的代码是一种谜语般的艺术，出谜语和猜谜语的人们都能从中获得巨大的精神满足&lt;/blockquote&gt;但是，請不要輕易的把 Ruby 歸於「華而不實」這一派。Robbin 老大也在&lt;a href="http://robbin.javaeye.com/blog/153749"&gt;這裡&lt;/a&gt;講到&lt;br /&gt;&lt;blockquote&gt;C++的魔幻语法会导致代码的可读性变差，而Ruby的魔幻语法会导致代码的可读性大大提高。&lt;br /&gt;&lt;br /&gt;不论是matz本人，还是整个Ruby社区，Rails社区诸多开源项目的作者，抑或整个Ruby和Rails开发者社区，在一个编程哲学问题上是高度统一的，这就是：&lt;br /&gt;&lt;br /&gt;强调程序员的快乐编程，追求人性化编程，在代码的可读性上面有偏执的追求，拒绝难以阅读的代码和难用的API。也就是所谓的coding for fun! &lt;/blockquote&gt; Ruby 奇妙的手法，以及 DSL 的技巧，都是為了達到跟 Python 同樣的 Promise Land ，那就是「code 可讀性」。只是兩者作法不同而已。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;兩者的不同&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;兩者最大的不同是在「&lt;span style="font-weight: bold;"&gt;開發者的審美觀以及開發風格&lt;/span&gt;」上。不是語言的不同，是使用者個性上的不同。&lt;br /&gt;&lt;blockquote&gt; 回到开头的话题，Ruby是一个典型的魔幻语言，而Python则是简约派的代表。两个语言的支持人群在审美观念和开发风格方面差距非常大。初学Ruby和Python的人，都会感受到一种欣喜和兴奋，但是原因却不太一样。Ruby的学习者会惊喜于很多新的表达方式，比如 :attr_accessor 之类的魔幻特性，而Python学习者则会惊喜于实现具体功能的简洁性。可以说从一开始他们追求的就是不同的东西。随着学习的深入，Python开发者当然也会发现Python中的不少深入的特性，不过却并不倾向于滥用它们。长次以往，Python人群对任何语言的魔幻面都会产生一种厌恶感。我认识的一个Django开发者，就明确表示，就算RoR比Django开发效率高一点，也绝不使用Ruby，因为Ruby这个语言充满了“不必要的小聪明”。&lt;/blockquote&gt;高手果然是高手，好露骨的講法。Python 人對於「語言的魔幻面」，或是你要稱為「奇技淫巧」有種本質上的厭惡感，很多 Ruby 人引以為傲的東西，都會被視為「惡魔」。儘管 Python 也可以玩出些好玩的把戲，但是他們的中心思想讓他們「選擇不去作」。&lt;br /&gt;&lt;br /&gt;而 Ruby 正如上面所說得，Ruby 人會被鼓勵使用「語言的魔幻面」，並且從中獲得相當的精神上的樂趣。但是跟「華而不實」最大的不同，是在於 Ruby 是利用語言的炫技，達到超乎想像的開發效率跟可讀性。最後，偉大的傑作誕生了，Ruby on Rails 用本身的「魔幻面」，反而達成了比PHP 這種 Web 專用的簡約語言的更高的可讀性。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;本質上的不同？還是人的不同？&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;人的 tone 不同，才是真正的問題所在。或許雙子座的我，永遠不會欣賞  Python :p&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;奇想&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;  &lt;br /&gt;不知道為什麼，寫這篇文章的時候，總是把魔幻語言想成魔法師，簡約語言想成戰士。所以腦中一直圍繞著 Ruby 是魔法技能點數 10 的魔法師，前面還有一個血防加到滿的戰士在前面罩著（Java），然後組隊一起打怪。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6694571877222626605?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/6694571877222626605/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=6694571877222626605' title='16 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6694571877222626605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6694571877222626605'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/01/ruby-python.html' title='Ruby 跟  Python 本質上不同'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-6866530760131742250</id><published>2008-01-08T10:17:00.000+08:00</published><updated>2008-01-08T13:39:34.008+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tiobe_index'/><title type='text'>恭喜 Python 成為 programming language of 2007</title><content type='html'>&lt;a href="http://www.tiobe.com/tpci.htm"&gt;TIOBE 原文&lt;/a&gt;，&lt;a href="http://inet6.blogspot.com/2008/01/2007-python.html"&gt;翻譯文&lt;/a&gt;在此。值得稱讚的是，Python 首度超越 Perl 。&lt;br /&gt;&lt;br /&gt;這年頭 Scripting Language 當道，Ruby 是2006 年的年度語言，Python 成 2007年的年度語言。明年 Ruby 再把這個殊榮拿回來吧 :p&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6866530760131742250?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/6866530760131742250/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=6866530760131742250' title='7 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6866530760131742250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6866530760131742250'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/01/python-programming-language-of-2007.html' title='恭喜 Python 成為 programming language of 2007'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-4438333623516300833</id><published>2008-01-07T02:15:00.000+08:00</published><updated>2008-01-07T02:18:46.963+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='gem'/><title type='text'>ludy 0.0.9 released</title><content type='html'>其實後來的更新幾乎都是亂寫了，這次的更新也差不了太多。大抵上就是增加個 C++ TR1 style 的 bind... 用起來的味道大概是這樣：（如果熟 C++ TR1/boost bind 的話，一眼就知道了）&lt;br /&gt;&lt;br /&gt;assert_equal [9,8,7], ([1,2,3].map &amp;(lambda{|lhs, rhs| lhs-rhs}.bind 10, :_1))&lt;br /&gt;assert_equal [3,2,1], (lambda{|a,b,c| [a,b,c]}.bind :_3, :_2, :_1)[1,2,3]&lt;br /&gt;assert_equal [1,9,3], (lambda{|a,b,c| [a,b,c]}.bind :_1, 9, :_3)[1,2,3]&lt;br /&gt;assert_equal [9,2,3], (lambda{|a,b,c| [a,b,c]}.bind 9)[2,3]&lt;br /&gt;assert_equal [9,4,2], (lambda{|a,b,c| [a,b,c]}.bind 9, :_3)[2,3,4]&lt;br /&gt;&lt;br /&gt;不過我總覺得 ludy 應該可以繼續走下去才對。所以我想在下次做一次 major update, 版本號大概就是 0.1.0 吧。會做的改變大概如下：&lt;br /&gt;&lt;br /&gt;1. 整理 project directory structure, 現在根本就是亂七八糟。我想大概會用 gem bones 去做吧。其實我是比較 prefer hoe, 但是 bones 的 rake task 有 namespace 比較漂亮... 如果 hoe 會更新到使用 namespace 的話，我再 switch 過去。現階段，我想 bones 是個不錯的選擇。&lt;br /&gt;&lt;br /&gt;使用這種東西的好處，當然就是不用去設計 directory structure... 而且自己寫 gemspec 老實說也真的是滿麻煩的，bones 和 hoe 都有 rake task 幫我 build gem 檔，甚至還有 publish, 多方便。&lt;br /&gt;&lt;br /&gt;2. 思索 puzzle_generator 的未來。其實他跟 ludy 一點關係都沒有，只是我為了使用 svn server 所以才把他加到 ludy 上的。到底 puzzle_generator 應該分出來，還是在 ludy 中找到一個位子？分出來的話，又該分去哪裡？&lt;br /&gt;&lt;br /&gt;3. ruby 1.9 compatibility, 我剛剛稍微測試了一下，有幾個比較髒的東西在 ruby 1.9 是跑不起來的。這個應該要想辦法修掉，ruby 1.9 很棒的。除了效能好很多以外，多了很多我想要很久的功能，能早點轉過去就早點。可惜的是 1.9 問題還很多，而且很多 gem 沒辦法在上面跑，所以 1.8 還是必備的。現階段會讓 1.8 和 1.9 都相容，等 1.9 夠穩了，就不會考慮支援 1.8 了。&lt;br /&gt;&lt;br /&gt;4. require path 的麻煩問題。去看看 facets, 他們對於 require path 大概也很頭痛吧。從 2.0.0 就整個把 require path 翻修過，結果還有大 bug, 害我完全沒辦法用。果然很快就推出 2.0.1 了...。還是 2.0.1 ~ 2.0.2 的階段，我忘了。反正就是很可笑的狀況，名稱衝突之類的。bug 期間我是暫時 monkey patch.&lt;br /&gt;&lt;br /&gt;再看看 rubygems, 一開始有個 require_gem. 而我，卻也弄了個 require_ludy. 沒辦法，因為很難寫一個在任何情況下都有效的 require, 所以才搞出那種東西。但是現在我覺得，還是應該多為 user 想想，畢竟連 rubygems 都捨棄 require_gem, 我也不該繼續使用 require_ludy 才對。&lt;br /&gt;&lt;br /&gt;無奈這真的是個很大的問題，可能勢必得做得不要那麼 general 吧？大致問題如下：&lt;br /&gt;a. 使用 gem install 時可以正常 require.&lt;br /&gt;b. 把東西全部 copy 到 project path 時, 讓 -I 可以 work.&lt;br /&gt;&lt;br /&gt;其實簡單地說，就是希望不要 gem install 也可以輕鬆放到專案中使用。不過也許得放棄這個要求吧？因為實際在寫時，就會發現很多問題都跟這有關。如果能「假設」gem 一定有安裝起來的話，很多考量就可以不用做了。&lt;br /&gt;&lt;br /&gt;事實上，不需要安裝 gem 也能 work, 對於開發也很有用。因為我可以改改程式就測試最新的結果，而不必自己裝一份。所以，還是再看看吧。還是希望能有好方法。&lt;br /&gt;&lt;br /&gt;5. unit testing. 既然是 unit testing, 當然就要有能夠分開 test 的動作。我希望可以 ruby test/tc_bind.rb, 也可以 rake test 測試所有的 unit test. 之前因為沒在用 rake, 我自己寫了個 ts_ludy.rb, 大概就是做這件事。所以 ruby test/ts_ludy.rb 就可以跑所有的測試。&lt;br /&gt;&lt;br /&gt;而我發現，如果照 unit test 原先的設計，把所有東西都 require 起來再跑，執行效能會變得很爛很爛。原因我不是很清楚... 所以後來我改變作法，變成一個個去跑每個 unit test, 然後把輸出結果蒐集起來，再報告出去。這樣的好處就是跑得速度真的快太多了，好幾倍的差別。缺點當然就是，這樣做挺詭異的...&lt;br /&gt;&lt;br /&gt;所以關於 testing 的部份，也還需要再整理一下。大致就是希望能單獨跑也能一起跑。另一方面，我要求 testing 所使用的 lib 應該要是相對路徑下的，而不是 gem 上的。理由同 require path 上面的描述。&lt;br /&gt;&lt;br /&gt;其實對於 require path 和 unit testing 的部份，我花了不少功夫，不過成果其實還滿差的。當時看是沒什麼感覺，現在看覺得實在很醜。&lt;br /&gt;&lt;br /&gt;6. 去掉 shebang, 那很蠢。（那時候對 shell 太不熟了）&lt;br /&gt;&lt;br /&gt;7. ludy_ext.rb&lt;br /&gt;這東西，本來是想放各個沒在 Ludy module 下的東西，不過這樣成長太噁心了。應該學學 facets, 一個 method 一個檔才對。所以這部份也要切開，整理一下。&lt;br /&gt;&lt;br /&gt;8. 整合之前為了 shooting-cubes 做的一些 rake task, 還有 erb meta-programming 的一些相關 method. 這個，和 puzzle_generator 一樣好像有點尷尬，不太屬於 ludy 的範疇。&lt;br /&gt;不過在整個 ludy 東西還很少的狀況下，我希望盡量整合一些 lib.&lt;br /&gt;&lt;br /&gt;9. 儘快整合 multi, 那個 multi-method 的 lib. 我在想，我可能自己實作一份，就不要直接把他吃進來。multi 是 MIT license, 我想我直接吃進來應該沒問題，只是整個感覺就很怪，而且他的程式有些部份我不太滿意，所以也許我自己做一份還是比較好，這樣也不用想怎麼合併。&lt;br /&gt;&lt;br /&gt;如果確實做出來了，那大概就只留一份 NOTICE 或感謝之類的，就不保留原本的 require path 了。不然，我真的覺得那樣很醜，像是分裂的個體似的。&lt;br /&gt;&lt;br /&gt;10. 修改一些文字說明，包含 README, CHANGES, description 之類的。現在的格式已經有點接近亂寫了。另一方面，也希望稍微修改一下 rubyforge 上的 release 結構。&lt;br /&gt;&lt;br /&gt;11. 撰寫 rdoc, 完全沒 doc 其實也有點奇怪...&lt;br /&gt;&lt;br /&gt;*&lt;br /&gt;&lt;br /&gt;所有的 source code 都採用 Apache License 2.0, 希望下次的更新可以涵蓋以上幾點。&lt;br /&gt;&lt;br /&gt;btw, bind 實作只有 13 行（含註解）&lt;br /&gt;&lt;br /&gt;安裝：&lt;br /&gt;gem install ludy&lt;br /&gt;&lt;br /&gt;取得所有程式：&lt;br /&gt;svn checkout http://ludy.rubyforge.org/svn/&lt;br /&gt;or&lt;br /&gt;svk mirror http://ludy.rubyforge.org/svn/ //mirror/ludy&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4438333623516300833?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/4438333623516300833/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=4438333623516300833' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4438333623516300833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4438333623516300833'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/01/ludy-009-released.html' title='ludy 0.0.9 released'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-1348546245339153066</id><published>2008-01-04T10:00:00.000+08:00</published><updated>2008-01-04T10:35:28.717+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mongrel'/><title type='text'>Rails Is A Ghetto</title><content type='html'>先說好，Mongrel 是一個 Team ，所以 Zed Shaw  的離開不代表 Mongrel 的停擺，不過該開始尋求更好的 Application Server 摟。&lt;br /&gt;&lt;br /&gt;Zed Shaw （Mongrel 的作者）在去年的 12/15號&lt;a href="http://www.zedshaw.com/blog/announcing_my_retirement.html"&gt;宣告他封鍵盤&lt;/a&gt;，不再 Coding 了。然後又在去年的最後一天發表了一篇攻擊性言論相當強的文章，&lt;a href="http://www.zedshaw.com/rants/rails_is_a_ghetto.html"&gt;Rails is a Ghetto&lt;/a&gt;。裡面提到許多 Rails 社群的不良行為，並且用相當攻擊性的語氣來批評這些行為。這對 Rails 社群的確有很大的傷害，不過有多大那很難說。&lt;br /&gt;&lt;br /&gt;Zed Shaw 宣佈他不是 Ruby Guy，並且想轉向 Python，Factor，Lua 等語言看看。&lt;br /&gt;&lt;blockquote&gt;"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."&lt;br /&gt;&lt;/blockquote&gt;大家想看去看原文吧 :) 。你不用去期待裡面有啥技術，Performance ，語言架構的比較。裡面只罵人跟公司（ThoughtWork）。我很不喜歡這篇文章，因為語氣不只是差，還有許多人身攻擊&lt;br /&gt;&lt;blockquote&gt;Dave Thomas Ain’t No Sammy Sosa (He’s Just Fat)&lt;/blockquote&gt;之類的話語。更讓我覺得 Zed Shaw 的 EQ 似乎不是很好。&lt;br /&gt;&lt;br /&gt;不過，Zed Shaw 對於 Ruby on Rails 的社群貢獻是毋庸置疑的，至少讓我對你唱一句&lt;br /&gt;&lt;blockquote&gt;Goodbye My Love，我的愛人再見&lt;/blockquote&gt;祝你在新的社群有好的發展，還有 Ruby 社群沒有加蓋，你在外面受到不好的遭遇可以游回來呀。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1348546245339153066?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/1348546245339153066/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=1348546245339153066' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1348546245339153066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1348546245339153066'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/01/rails-is-ghetto.html' title='Rails Is A Ghetto'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-7856423397713892445</id><published>2008-01-01T16:58:00.000+08:00</published><updated>2008-01-01T17:11:45.853+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='talk'/><title type='text'>用 Blogger 寫技術類型文章的優勢</title><content type='html'>我當初選用 Blogger 寫 LightyROR 這個技術類型的 Blog ，就是看在&lt;br /&gt;&lt;br /&gt;1. 技術人員都用 Google&lt;br /&gt;2. Google 「應該」會對 Blogger 作技術文章搜尋結果作最佳化&lt;br /&gt;&lt;br /&gt;請注意，是應該，而不是肯定。我&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;「猜」&lt;/span&gt;&lt;/span&gt; Google 當然會對自家產品稍微愛護一下，而看我 Blog 的人應該都是用 Google ，所以我選擇 Blogger 。&lt;br /&gt;&lt;br /&gt;結果今天發生了一件事情，我四點寫了一篇&lt;a href="http://lightyror.thegiive.net/2008/01/centos-51-rmagick-works.html" class="l" onmousedown="return clk(this.href,'','','res','2','')"&gt;&lt;span style="color: rgb(204, 0, 51);"&gt; CentOS&lt;/span&gt; 5.1 + &lt;span style="color: rgb(204, 0, 51);"&gt;RMagick&lt;/span&gt; works&lt;/a&gt;，結果一個小時後我 Google 搜尋「CentOS  RMagick」文章的時候，發現已經進入 Google Search資料庫，並且排名第二名&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_8vS0KjIsbko/R3oDXbbJHWI/AAAAAAAAALk/kKeTdEVaOk4/s1600-h/screen-capture.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_8vS0KjIsbko/R3oDXbbJHWI/AAAAAAAAALk/kKeTdEVaOk4/s320/screen-capture.png" alt="" id="BLOGGER_PHOTO_ID_5150432824885058914" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;雖然不能說 Google 有對 Blogger 的文章有特別愛護，但是寫完文章後，一個小時進入搜尋搜尋資料庫，也算是另類的優勢。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7856423397713892445?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/7856423397713892445/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=7856423397713892445' title='4 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7856423397713892445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7856423397713892445'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/01/blogger.html' title='用 Blogger 寫技術類型文章的優勢'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_8vS0KjIsbko/R3oDXbbJHWI/AAAAAAAAALk/kKeTdEVaOk4/s72-c/screen-capture.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-9045130820943854685</id><published>2008-01-01T15:59:00.000+08:00</published><updated>2008-01-01T16:43:26.707+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rmagick centos 安裝'/><title type='text'>CentOS 5.1 + RMagick works</title><content type='html'>&lt;span style="font-weight: bold;"&gt;昨天，我要在 CentOS &lt;/span&gt;上面灌 RMagick。我 google 了一下，發現有位卧得罚先生寫關於 &lt;a href="http://hi.baidu.com/rainchen/blog/item/089ef7364497de320a55a9a3.html"&gt;CentOS 下面安裝 RMagick 的辛酸跟血淚&lt;/a&gt;，洋洋灑灑六到七頁，最後成功了還不忘加句「CentOS Sucks」。我發現到 &lt;a href="http://twitter.com/xdite/statuses/542402872"&gt;XDite 也又 twitter&lt;/a&gt; 「&lt;span style="font-style: italic;"&gt;CENTOS 裝 rmagick ...困難重重....&lt;/span&gt;」，這讓我非常的好奇，一心想看看在 Fedora 跟 Ubuntu 安裝都是瞬殺的 RMagick ，到底在 CentOS 上面出了啥問題。結果發現這條路好漫長，大概搞了半天以上吧......結論其實很簡單&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;CentOS 預設 FreeType Lib 是爛掉的，重新 compile  即可。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;一開始我想看看&lt;a href="http://rubyworks.rubyforge.org/"&gt;RubyWorks&lt;/a&gt; ，因為他們有懶人包一次包好所有 Ruby on Rails 的東西。我發現到他們網站上面 Optional Package 宣稱他們有包好 RMagick&lt;br /&gt;rubygem-rmagick (librmagick-ruby in Debian/Ubuntu repository.) – interface between the Ruby programming language and the ImageMagick® and GraphicsMagick image processing libraries.&lt;br /&gt;但是我在 RubyWorks 的 yum 中找不到，所以就當沒有這東西存在。然後，使用 yum 安裝 ImageMagick ，再用 gem 安裝 RMagick ，發現 CentOS ImageMagick 的版本太舊，RMagick 2.0 不支援。&lt;br /&gt;&lt;br /&gt;下載最新的 IMageMagick ，然後用 gem 安裝 RMagick 看似沒問題，但是當我想測試一下，按下&lt;br /&gt;ruby -rrubygems -e "require 'RMagick'; puts Magick::Long_version;"&lt;br /&gt;就發現有許多 Error 等著我。當我把這些 Error 放到網路上，結果發現沒有幾個回答。大部分都是叫我回去看&lt;a href="http://rmagick.rubyforge.org/install-faq.html"&gt; RMagick 的 Install Note&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;當然啦，別人叫我們看Install Note，就是代表「你並不了解這個東西」，所以我乖乖的看了一下我發現 RMagick 需要&lt;br /&gt;&lt;ol&gt;&lt;li&gt;FreeType&lt;/li&gt;&lt;li&gt;Ghostscript fonts&lt;/li&gt;&lt;li&gt;JPEG&lt;/li&gt;&lt;li&gt;PNG&lt;/li&gt;&lt;li&gt;WMF&lt;/li&gt;&lt;/ol&gt;這幾個 Image Lib ，當我確認過 CentOS 都有安裝這些 Lib 之後，很可惜的，Error 一再的出現，就這樣陷入了一再重複的地獄。最後我從&lt;a href="http://jacqueschirag.wordpress.com/2007/12/19/linux-commands-to-install-imagemagick-and-rmagick/"&gt;這個網頁&lt;/a&gt;發現到&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;CentOS 預設 FreeType Lib 是爛掉的。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;這就是最後的解答。So，請下載 FreeType 的 Lib ，重新 compile ，然後 RMagick 就會成功。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;以下是 Step by Step 安裝&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;我在一台乾淨的 CentOS 上面安裝成功過。下面安裝版本，CentOS 5.1 + gcc 4.1.2 + ImageMagick 6.3.7 + FreeType 2.3.5 + rmagick 2.0 或是 rmagick 1.15.12。&lt;br /&gt;&lt;br /&gt;1. 安裝 GCC / G++&lt;br /&gt;yum install gcc-c++ compat-gcc-32 compat-gcc-32-c++&lt;br /&gt;&lt;br /&gt;2. Install 相關 lib&lt;br /&gt;yum install glib glib2 zlib-devel libpng libjpeg libtiff ghostscript&lt;br /&gt;&lt;br /&gt;3. 下載 &lt;a href="http://download.savannah.gnu.org/releases/freetype/freetype-2.3.5.tar.gz"&gt;FreeType 2.3.5 &lt;/a&gt;，make&lt;br /&gt;&lt;br /&gt;4. 下載 &lt;a href="http://www.imagemagick.org/"&gt;ImageMagick&lt;/a&gt;，make&lt;br /&gt;你可以用 convert --version 確認是否安裝成功&lt;br /&gt;&lt;br /&gt;5. gem i rmagick&lt;br /&gt;你可以用&lt;br /&gt;ruby -rrubygems -e "require 'RMagick'; puts Magick::Long_version;"&lt;br /&gt;確認是否安裝成功。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-9045130820943854685?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/9045130820943854685/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=9045130820943854685' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/9045130820943854685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/9045130820943854685'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2008/01/centos-51-rmagick-works.html' title='CentOS 5.1 + RMagick works'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-2358634651668382575</id><published>2007-12-30T09:57:00.000+08:00</published><updated>2008-01-08T11:40:29.363+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Ruby 1.9 Release</title><content type='html'>Ruby 1.9 Release了，根據Ruby慣例，版本小數點後面的數字偶數是穩定版本，奇數是測試用的版本。所以 Ruby 1.9 算是 Ruby 2.0 之前的開發版本，現行的穩定版本還是 Ruby 1.8，所以請不要把你公司的 Production 機器都改成 Ruby 1.9。&lt;br /&gt;&lt;br /&gt;1.9 除了&lt;a href="http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9"&gt;語法上面的演進&lt;/a&gt;以外，最大的不同就是在於內建 YARV 這個 VM。對於 Ruby 整體效能有相當大的增快，如果 Ruby 跟 Python  2 Fibonacci Sequence 的測試，大概比 Python 2 快了三倍。However ，跟幾年前的 Release 比速度，還真的沒啥好誇耀的 :p&lt;br /&gt;&lt;br /&gt;Download 點在這&lt;br /&gt;ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.0-0.tar.gz&lt;br /&gt;&lt;br /&gt;Change in Ruby 1.9&lt;br /&gt;http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-2358634651668382575?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/2358634651668382575/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=2358634651668382575' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2358634651668382575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2358634651668382575'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/12/ruby-19-release.html' title='Ruby 1.9 Release'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-2937406849468536106</id><published>2007-12-26T13:37:00.000+08:00</published><updated>2007-12-26T14:02:47.676+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='beast'/><title type='text'>Beast 在 Rails 2.0.2 不能啟動的解決方式</title><content type='html'>昨天 安裝&lt;a href="http://beast.caboo.se/"&gt;Beast&lt;/a&gt; Trunk ，發現在最後 rake db:schema:load 遇到&lt;br /&gt;&lt;blockquote&gt;rake aborted!&lt;br /&gt;undefined method `whiny_protected_attributes=' for ActiveRecord::Base:Class&lt;/blockquote&gt;這樣的 error。根據&lt;a href="http://chinaonrails.com/topic/view/1056.html"&gt;網路上的回答&lt;/a&gt;，應該是 Rails 2.0.2 搞得鬼，解決方式根據&lt;a href="http://msblog.cn/2007/12/19/8"&gt;這個網頁&lt;/a&gt;講的，在 config/enviroment.rb 裡面將這行 comment 起來即可&lt;br /&gt;&lt;blockquote&gt;#config.active_record.whiny_protected_attributes = false&lt;br /&gt;&lt;/blockquote&gt;話說，beast 已經 800 多行了，乾脆改成千行以下的 forum 好了 :p&lt;br /&gt;&lt;br /&gt;Ps.&lt;br /&gt;Beast 安裝方式&lt;br /&gt;1. 下載下來 beast trunk code&lt;br /&gt;&lt;blockquote&gt;svn checkout http://svn.techno-weenie.net/projects/beast/trunk beast&lt;br /&gt;&lt;/blockquote&gt;2. cp config/database.example.yml config/database.yml 並且修改他&lt;br /&gt;3. 建立 schema&lt;br /&gt;rake db:schema:load&lt;br /&gt;4.  修改 config/environment.rb. 裡面的 PASSWORD_SALT&lt;br /&gt;5.  安裝額外的 Gem 像是 RedCloth 或是 ruby-openid&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-2937406849468536106?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/2937406849468536106/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=2937406849468536106' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2937406849468536106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2937406849468536106'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/12/beast-rails-202.html' title='Beast 在 Rails 2.0.2 不能啟動的解決方式'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-5249789288016717967</id><published>2007-12-10T19:06:00.000+08:00</published><updated>2007-12-10T19:39:26.314+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>Leopard，Terminal，Vim，and .... UTF-8</title><content type='html'>最近買了新的 MacBook ，Leopard  到目前感覺都還很不錯，尤其是大幅度改進的 Terminal.app 。不過，跟我預料的一樣，Terminal 的 UTF-8 問題依舊沒有設定好。所以花了點時間 survey ，順便把一直困擾我的 vim 中文問題一起解決。&lt;br /&gt;&lt;br /&gt;Leopard 內建的 vim 是 version 7.0.234  ，GNU bash 是  3.2.17 ，這幾個版本支援 UTF-8 都沒有任何問題，所以其實只是設定檔的問題。&lt;br /&gt;&lt;br /&gt;1. 修改 ~/.profile&lt;br /&gt;加入&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;export LANG=zh_TW.UTF-8&lt;/blockquote&gt;2.  ~/.vimrc&lt;br /&gt;加入&lt;br /&gt;&lt;blockquote&gt;if has("multi_byte")&lt;br /&gt;  set enc=utf-8&lt;br /&gt;  set fenc=utf-8&lt;br /&gt;  set termencoding=utf-8&lt;br /&gt;  set fileencodings=utf-8,ucs-bom,big5,latin1&lt;br /&gt;else&lt;br /&gt;  echoerr "Sorry, this version of (g)vim was not compiled with multi_byte"&lt;br /&gt;endif&lt;br /&gt;&lt;/blockquote&gt;不確定是否有沒有更好的設定方式，不過，我已經滿意了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-5249789288016717967?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/5249789288016717967/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=5249789288016717967' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/5249789288016717967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/5249789288016717967'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/12/leopard.html' title='Leopard，Terminal，Vim，and .... UTF-8'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-2567245944761891420</id><published>2007-11-05T08:28:00.001+08:00</published><updated>2007-11-05T23:58:19.173+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><title type='text'>JRuby 1.1 Beta 1 Release；這個世界最快的 Ruby Interpreter?</title><content type='html'>&lt;a href="http://docs.codehaus.org/display/JRUBY/2007/11/02/JRuby+1.1b1+Released"&gt;JRuby 1.1 終於出 Beta 了&lt;/a&gt;，1.0 -&amp;gt; 1.1 主要的改進都是在於 Performance 的部份，結果是JRuby 已經在大多數的 Test 勝過現行的 Ruby 1.8.6，Ruby code 可以用 AOT 或是 JIT 來 compile 。並且兩者都比現行的 Ruby 來的快，memory 使用也比較少。&lt;br /&gt;&lt;br /&gt;當然宣稱歸宣稱，我們也該看看 real rails application performace 的表現如何。Nick Sieger 寫了一篇 &lt;a href="http://blog.nicksieger.com/articles/2007/10/25/jruby-on-rails-fast-enough"&gt;JRuby on Rails:Fast Enough&lt;/a&gt; 表示 JRuby on Rails 已經跟 Ru&lt;br /&gt;by on Rails ㄧ樣快速了。並且JRuby 核心開發者 Ola Bini表示&lt;a href="http://ola-bini.blogspot.com/2007/10/mystery-expos-on-jruby-performance.html"&gt; JRuby 已經在大&gt;多數的 Test 勝過 Ruby 1.8.6&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;公說公有理，婆說婆有理，那麼最起碼最起碼 JRuby 效能逼近 MRI Ruby 是不爭的事實。&lt;br /&gt;So，該是進場的時候嗎 :p&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-2567245944761891420?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/2567245944761891420/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=2567245944761891420' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2567245944761891420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2567245944761891420'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/11/jruby-11-beta-1-release-ruby.html' title='JRuby 1.1 Beta 1 Release；這個世界最快的 Ruby Interpreter?'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-3961317114407099114</id><published>2007-11-02T21:35:00.001+08:00</published><updated>2007-11-02T21:41:40.200+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><title type='text'>JRuby 1.0.2 Relase</title><content type='html'>&lt;a href-"http://docs.codehaus.org/display/JRUBY/2007/11/01/JRuby+1.0.2+Released"&gt;JRuby 發表了 1.0.2 版本&lt;/a&gt;，修正許多 Bug 跟支援了 Rails 1.2.5，Rails 1.2.5 跟  &lt;a href="http://www.hhtong.com/blog1/articles/2007/11/01/jruby-20071101-rails"&gt;JRuby 1.0.1 有問題的人&lt;/a&gt;請升級到 JRuby 1.0.2。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-3961317114407099114?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/3961317114407099114/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=3961317114407099114' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3961317114407099114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3961317114407099114'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/11/jruby-102-relase.html' title='JRuby 1.0.2 Relase'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-7005126621883248138</id><published>2007-10-30T22:05:00.000+08:00</published><updated>2007-10-31T09:47:19.821+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mongrel'/><title type='text'>Mongrel 1.0.4 出了</title><content type='html'>&lt;ul&gt;&lt;/ul&gt;&lt;div&gt;在歷經將近十個月的等待， Mongrel 終於推出了 1.0.3 版，當然依照慣例，很快的馬上就被抓到很多 Bug，隔天就出了 Mongrel 1.0.4 版。安裝方式官方建議是&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;blockquote&gt;gem install mongrel --include-dependencies -P HighSecurity&lt;/blockquote&gt;不過，最重要的是 release note 最後一句&lt;br /&gt;&lt;blockquote&gt;Mongrel 1.1 is coming real soon now with JRuby support and a few other things.&lt;/blockquote&gt;&lt;code&gt;所以，Mongrel 1.1 要出來了，並且還要加上 JRuby Support。&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7005126621883248138?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/7005126621883248138/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=7005126621883248138' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7005126621883248138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7005126621883248138'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/10/mongrel-104.html' title='Mongrel 1.0.4 出了'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-2081384417189725043</id><published>2007-10-30T07:57:00.000+08:00</published><updated>2007-10-30T08:08:48.911+08:00</updated><title type='text'>It's all about JavaScript</title><content type='html'>&lt;b&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;進入公司至今已經一個多禮拜，因為 Project 因素，整天都在碰 Javascript。其實還蠻充實的，而且也學到不少東西，或許我該為這個Blog改個名字叫 LightyJS 之類 :p 很多時候當你真的寫過 Javascript，才發現 RJS 的好處。總之，或許我該多寫點 Javascript 的東西。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/b&gt;&lt;ul&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-2081384417189725043?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/2081384417189725043/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=2081384417189725043' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2081384417189725043'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2081384417189725043'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/10/its-all-about-javascript.html' title='It&apos;s all about JavaScript'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-5946909946231132948</id><published>2007-10-17T08:11:00.000+08:00</published><updated>2007-10-17T08:24:28.128+08:00</updated><title type='text'>新訓結束了，國防役開始</title><content type='html'>入伍前，PTT 上面的版眾已經告誡大家某營某連很可怕，但是還是被國防部排進去這個連隊。經過一連串的酸甜苦辣，我從某精實連出來了。因為這個連實在是很精實，所以沒時間看書。我的HTTP：The Definitive Guide也沒翻到百頁。接下來的一周，找房子，搬家，適應新公司等等大概可以讓我多忙個兩週。看來 LightyRoR 要重新出發可能也要等個幾天。對了，我國防役去友邁科技（主力產品 Urmap.com）。&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;還有，最近對讀 Rails Source，玩 Xen ，玩 Linux From Scratch，玩仙劍奇俠傳4 很有興趣。真不知道有沒有時間讓我這樣玩。會不會到最後，只有電動玩到了，其他的東西全部都沒時間呢 :p&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;總之，我回來了。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-5946909946231132948?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/5946909946231132948/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=5946909946231132948' title='4 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/5946909946231132948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/5946909946231132948'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/10/blog-post.html' title='新訓結束了，國防役開始'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-8430527692815295504</id><published>2007-09-08T16:27:00.000+08:00</published><updated>2007-09-08T16:39:00.111+08:00</updated><title type='text'>AK47 與 M16 補充</title><content type='html'>大家好，我又放假了。看到有人問我，上篇文章，意味著誰代表RoR。我只能說，沒有特別的誰代表誰。&lt;br /&gt;&lt;br /&gt;在技術水準差不多的狀態下，所謂的設計好壞其實只是取捨。Ak47 取了簡單，但是失去了準度。M16 強調準度，但是輕巧的設計卻換來了些許的不穩定，以及較高的訓練時間。換來的結果也沒有誰輸誰贏，只是剛好第三世界國家適合 AK47 ，美國適合 M16。&lt;br /&gt;&lt;br /&gt;越戰這個 case ，Ak47 遠勝於 M16，但是這是在叢林戰這個 domain。其實美軍打贏那麼多場戰役，很多其他的戰爭 case，M16 說不定在其他 case 壓的死死的。只是越戰名氣大而已。&lt;br /&gt;&lt;br /&gt;一切都只是需求的不同而已。&lt;br /&gt;&lt;br /&gt;軟體開發也是如此。在工程師水準相近的情況下，你的選擇通常都只是因為這個任務的需求，而非這個設計方式比較好。&lt;br /&gt;&lt;br /&gt;我所陳述的，是一段歷史，是一個工程設計哲學的頂尖對決，是一個值得去瞭解的他山之石。而非誰代表誰。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8430527692815295504?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/8430527692815295504/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=8430527692815295504' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8430527692815295504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8430527692815295504'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/09/ak47-m16_08.html' title='AK47 與 M16 補充'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-2081730241812596873</id><published>2007-09-01T13:05:00.000+08:00</published><updated>2007-09-01T23:07:02.510+08:00</updated><title type='text'>AK47 與 M16</title><content type='html'>大家好，我是 thegiive，我正在服國防役新訓，先跟大家打個招呼。最近一直沒時間碰 Ruby on Rails ，不過軍中倒是花了點時間研究步槍。賢者總是說到「觸類旁通」這件事情，我也剛好從步槍這種殺人兵器中，看到了一些東西，很值得軟體開發借鏡。在此先警告一下，我只是在陳述輕兵器設計哲學之間的比較，並非鼓吹輕兵器，戰爭等東西，如果認為槍枝是邪惡不能被提及之人，請勿進入本文。&lt;br /&gt;&lt;br /&gt;我研究的東西，就是號稱 20世紀最偉大的武器 AK47 ，跟屈居第二的 M16 的之間的瑜亮之爭。&lt;br /&gt;&lt;br /&gt;AK47 是由&lt;a href="http://zh.wikipedia.org/w/index.php?title=%E8%98%87%E8%81%AF&amp;variant=zh-tw" title="蘇聯"&gt;蘇聯&lt;/a&gt;槍械設計師&lt;a href="http://zh.wikipedia.org/w/index.php?title=%E7%B1%B3%E5%93%88%E4%BC%8A%E5%B0%94%C2%B7%E5%AD%A3%E8%8E%AB%E8%B4%B9%E8%80%B6%E7%BB%B4%E5%A5%87%C2%B7%E5%8D%A1%E6%8B%89%E4%BB%80%E5%B0%BC%E7%A7%91%E5%A4%AB&amp;amp;amp;variant=zh-tw" title="米哈伊尔·季莫费耶维奇·卡拉什尼科夫"&gt;米哈伊爾·季莫費耶維奇·卡拉什尼科夫&lt;/a&gt;設計的&lt;a href="http://zh.wikipedia.org/w/index.php?title=%E8%87%AA%E5%8A%A8%E6%AD%A5%E6%9E%AA&amp;variant=zh-tw" title="自动步枪"&gt;自動步槍&lt;/a&gt;。這款武器號稱槍中之王，很多第三世界國家的戰爭都看到他的身影。可以說是哪裡有戰爭，那裡就有  AK47。有這樣一句話：「&lt;a href="http://zh.wikipedia.org/w/index.php?title=%E7%BE%8E%E5%9C%8B&amp;amp;variant=zh-tw" title="美國"&gt;美國&lt;/a&gt;出口的是&lt;a href="http://zh.wikipedia.org/w/index.php?title=%E5%8F%AF%E5%8F%A3%E5%8F%AF%E6%A8%82&amp;variant=zh-tw" title="可口可樂"&gt;可口可樂&lt;/a&gt;，&lt;a href="http://zh.wikipedia.org/w/index.php?title=%E6%97%A5%E6%9C%AC&amp;amp;variant=zh-tw" title="日本"&gt;日本&lt;/a&gt;出口的是&lt;a href="http://zh.wikipedia.org/w/index.php?title=%E7%B4%A2%E5%B0%BC&amp;variant=zh-tw" title="索尼"&gt;Sony&lt;/a&gt;電器，而&lt;a href="http://zh.wikipedia.org/w/index.php?title=%E8%98%87%E8%81%AF&amp;amp;variant=zh-tw" title="蘇聯"&gt;蘇聯&lt;/a&gt;出口的是AK47。」&lt;br /&gt;&lt;br /&gt;這不是沒有原因的。 AK47 當初設計的哲學，就是為了「&lt;span style="font-weight: bold;"&gt;簡單&lt;/span&gt;」。他被設計成為任何民眾，在沒有人教導，沒有任何工具，依舊可以在三個小時之內可以徒手拆解結合，並且裝子彈射擊，由此可以知道他的「簡單」，到底是簡單到什麼程度。&lt;br /&gt;&lt;br /&gt;再來因為俄羅斯環境氣候糟糕，他將內部機構組織設計為較粗糙，這代表不容易因為沙土，泥水進去而導致不能擊發，也就是他當初就是為了設計為可以&lt;span style="font-weight: bold;"&gt;穩定&lt;/span&gt;的擊發子彈，就算再惡劣的環境也是如此。後來因為 AK47 大流行，參加了許多場戰爭，擁有相當多的實戰測試，導致他的擊發穩定性更上一層樓。有人戲稱「AK47 掉到泥水中，沒關係甩一甩，繼續打」。&lt;br /&gt;&lt;br /&gt;但是當初社記者因為為了「簡單」，「穩定」，損失了些許射擊準度。導致 300M 外射擊準度很差。&lt;br /&gt;&lt;br /&gt;M16 系列是屬於美國系統，他當初設計的哲學就是為了&lt;span style="font-weight: bold;"&gt;擁有穩定的設計準度&lt;/span&gt;，以及&lt;span style="font-weight: bold;"&gt;良好的射擊距離&lt;/span&gt;。所以他採取相當巧妙的設計（我們輕兵器教官是這樣講的，我沒有研究很深），但是越精巧的系統代表&lt;span style="font-weight: bold;"&gt;容錯率越低&lt;/span&gt;， 第一版 M16 對於環境的容忍程度較差，很容易因為環境因素導致卡彈。美軍在沙漠風暴之中，就常聽說美軍為了避免沙子進入槍口，用保險套套住槍口，形成一種很詭異的情況。&lt;br /&gt;&lt;br /&gt;綜合比較兩者優劣，很明顯的 M16 在射擊準度上面優於 AK47 許多，但是耐用度上面，第一版的 M16 可以說是遠遠輸了 AK47，一直到 M16A2 才比較好一點，不過還是輸給 Ak47 。&lt;br /&gt;&lt;br /&gt;使用率上面，AK47遠遠的贏過 M16，傳說 AK47 有一億隻之多。造成 AK47 大流行的原因很多，&lt;br /&gt;&lt;ol&gt;&lt;li&gt;一來是因為構造簡單，上手簡單，士兵幾乎不用訓練就可以擊發，所以許多第三世界國家喜歡使用 AK47。&lt;/li&gt;&lt;li&gt;再來就是因為構造簡單，容易仿造，所以很多國家都自己仿冒 AK47，傳說十支 Ak47 只有一支是正版的 AK47。&lt;/li&gt;&lt;li&gt;再來就是如果你有看軍火之王這部片子，裡面講到蘇聯瓦解，許多將軍失去以前的榮光，為了錢，他們將軍火庫裡面成千上萬的 AK47 盜賣給軍火商，導致黑市 AK47 大流行，既便宜又好用。&lt;/li&gt;&lt;li&gt;最後雖然 AK47 不準，但是第三國家沒有資源去花時間訓練士兵射擊準度，所以使用 AK47 根本沒差&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;這裡必須要提一件題外話，如果你看過血鑽石這部片子，就知道他們是怎麼訓練娃娃兵的。而娃娃兵雖然知識水準不高，但是因為 AK47 實在是使用上太簡單了，所以導致軍閥隨隨便便訓練娃娃兵，他們都可以上手，拿槍來殺人， AK47 的簡單某種程度導致娃娃兵的大流行。這是讓我每次看到都覺得很荒謬的一件事情。&lt;br /&gt;&lt;br /&gt;真正決定 AK47 王者地位的戰役就是越戰。越南一方使用 AK47，美軍使用 M16。越戰是叢林戰為主，叢林戰的攻擊射程可能根本不到 10 m ，在叢林 AK47 跟 M16 射擊射程都是一樣的，也就是 M16 的強項射擊距離跟經準度就跟廢了一樣。再加上叢林環境太過惡劣了，M16的低容錯率造成大量卡彈的發生，很多美軍屍體旁邊都有卡彈的 M16，代表他們是因為卡彈才死去的。到後來，甚至出現許多美軍將自己 M16 放在一旁，反而使用搶來的 Ak47 來打越南軍的怪現象。&lt;br /&gt;&lt;br /&gt;事後想想，AK47 早就已經實戰好幾年了，那時的穩定度以經是 3.0 版。M16 在越戰時穩定度還是 1.0 Pre release 版。再來剛好遇到 M16 強項被極小化，所以才會遇到被 AK47 八的那麼慘的情況。&lt;br /&gt;&lt;br /&gt;雖然剛剛講了那麼多 M16 的壞現象，但是他依舊美軍最佳的利器。因為美軍戰爭時需要「減少傷亡」，減少傷亡最好的方式就是拉遠戰鬥，所以 Ak47 只能較近距離的特性依舊不適合美軍。也就是說，沒有最好的槍枝，只有最適合這次任務的槍枝。&lt;br /&gt;&lt;br /&gt;所謂的簡單就是美，在 AK47 留下的最好的證明。簡單的設計容易修改，複製。產品正確率也較高。並且容易上手就容易造成流行。軟體又何嘗不是如此。&lt;br /&gt;&lt;br /&gt;穩定性的重要，在輕兵器的領域優先權是相當高的，畢竟子彈往身上跑過來的時候，誰都不希望自己手上的槍枝卡彈。越戰時，AK47就在這個領域上面遠遠勝過 M16，也為這次比試留下了勝利。當某個領域的要求穩定性，已經高到一個很重要的程度時，我們應該選擇比較穩定的設計，而非功能比較強大的設計。&lt;br /&gt;&lt;br /&gt;最後，沒有最好的槍枝，只有最合適這次任務的槍枝。同樣的，沒有最好的軟體，只有最符合這次任務需求的軟體。&lt;br /&gt;&lt;br /&gt;我們在這些輕兵器的歷史中，是不是看到許多軟體開發的影子呢。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-2081730241812596873?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/2081730241812596873/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=2081730241812596873' title='4 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2081730241812596873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2081730241812596873'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/09/ak47-m16.html' title='AK47 與 M16'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-3279984706941692070</id><published>2007-08-22T17:40:00.000+08:00</published><updated>2007-08-22T17:41:15.069+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nginx'/><category scheme='http://www.blogger.com/atom/ns#' term='安裝'/><title type='text'>Fedora Core 6 上安裝 beast (3)</title><content type='html'>覺得 pound + lighttpd 太麻煩嗎？又翻到一個應該不錯的選擇，&lt;br /&gt;是一個俄國人寫的 http server, 也具有 reverse proxy 和&lt;br /&gt;load balancing 的能力。&lt;br /&gt;&lt;br /&gt;godfat ~ 3.2$ port info nginx&lt;br /&gt;nginx 0.5.29, www/nginx (Variants: universal, dav, flv, mail, ssl)&lt;br /&gt;http://nginx.net/&lt;br /&gt;&lt;br /&gt;Nginx ("engine x") is a high-performance HTTP(S) server and reverse proxy,&lt;br /&gt;as well as an IMAP/POP3 proxy server. Nginx was written by Igor Sysoev for&lt;br /&gt;Rambler.ru, Russia's second-most visited website, where it has been running&lt;br /&gt;in production for over two and a half years. Igor has released the source&lt;br /&gt;code under a BSD-like license. Although still in beta, Nginx is known for&lt;br /&gt;its stability, rich feature set, simple configuration, and low resource&lt;br /&gt;consumption.&lt;br /&gt;&lt;br /&gt;這個字實在是很難記…不過討論翻來翻去，他 serve static file 的效能和&lt;br /&gt;lighttpd 在伯仲之間，而 load balancing 是正常可用的。所以與其使用&lt;br /&gt;pound + lighttpd, 單用 nginx 可以簡化一些流程。我想缺點就是設定上&lt;br /&gt;還是比 pound 複雜些，不過我個人是覺得比 lighttpd 簡單了。另外 nginx&lt;br /&gt;好像沒有 windows 版，而 pound 和 lighttpd 都有 windows 版，&lt;br /&gt;我想這對某些情況可能也是個考量吧？&lt;br /&gt;&lt;br /&gt;雖然之前因為英文文件太少所以不太流行，但最近似乎還算有蠻多人推薦的，&lt;br /&gt;而且這在俄國好像還蠻廣泛被使用的，試試應該無妨。&lt;br /&gt;&lt;br /&gt;sudo yum install nginx&lt;br /&gt;&lt;br /&gt;跟 lighttpd 一樣，一起丟到 beast 目錄下比較容易管理。&lt;br /&gt;cp /etc/nginx/nginx.conf \&lt;br /&gt;/home/YOUR_NAME/projects/beast/stable-1.0/config/nginx.conf&lt;br /&gt;cp /etc/nginx/mime.types \&lt;br /&gt;/home/YOUR_NAME/projects/beast/stable-1.0/config/mime.types&lt;br /&gt;前者是 config 檔，後者是 mime-type 設定檔，會被 include 進去。&lt;br /&gt;&lt;br /&gt;nano config/nginx.conf&lt;br /&gt;=======================&lt;br /&gt;user&amp;nbsp;YOUR_NAME&amp;nbsp;YOUR_NAME;&lt;br /&gt;worker_processes&amp;nbsp;1;&lt;br /&gt;pid&amp;nbsp;/home/YOUR_NAME/projects/beast/stable-1.0/tmp/pids/nginx.pid;&lt;br /&gt;&lt;br /&gt;error_log&amp;nbsp;/home/YOUR_NAME/projects/beast/stable-1.0/log/nginx_error.log;&lt;br /&gt;&lt;br /&gt;events&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;worker_connections&amp;nbsp;1024;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;http&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;include&amp;nbsp;/home/YOUR_NAME/projects/beast/stable-1.0/config/mime.types;&lt;br /&gt;&amp;nbsp;&amp;nbsp;default_type&amp;nbsp;application/octet-stream;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;log_format&amp;nbsp;main&amp;nbsp;'$remote_addr&amp;nbsp;-&amp;nbsp;$remote_user&amp;nbsp;[$time_local]&amp;nbsp;$request&amp;nbsp;'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'"$status"&amp;nbsp;$body_bytes_sent&amp;nbsp;"$http_referer"&amp;nbsp;'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'"$http_user_agent"&amp;nbsp;"$http_x_forwarded_for"';&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;access_log&amp;nbsp;/home/YOUR_NAME/projects/beast/stable-1.0/log/nginx_access.log&amp;nbsp;main;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;sendfile&amp;nbsp;on;&lt;br /&gt;&amp;nbsp;&amp;nbsp;keepalive_timeout&amp;nbsp;65;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;gzip&amp;nbsp;on;&lt;br /&gt;&amp;nbsp;&amp;nbsp;gzip_min_length&amp;nbsp;1100;&lt;br /&gt;&amp;nbsp;&amp;nbsp;gzip_buffers&amp;nbsp;4&amp;nbsp;8k;&lt;br /&gt;&amp;nbsp;&amp;nbsp;gzip_types&amp;nbsp;text/plain&amp;nbsp;text/html&amp;nbsp;text/xhtml&amp;nbsp;text/css&amp;nbsp;text/javascript;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;upstream&amp;nbsp;mongrel&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server&amp;nbsp;127.0.0.1:2000;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server&amp;nbsp;127.0.0.1:2001;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server&amp;nbsp;127.0.0.1:2002;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;server&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;listen&amp;nbsp;80;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server_name&amp;nbsp;localhost;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;location&amp;nbsp;~&amp;nbsp;^/(images|javascripts|stylesheets)/&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;/home/YOUR_NAME/projects/beast/stable-1.0/public&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expires&amp;nbsp;30d;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;location&amp;nbsp;/&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header&amp;nbsp;X-Real-IP&amp;nbsp;$remote_addr;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header&amp;nbsp;X-Forwarded-For&amp;nbsp;$proxy_add_x_forwarded_for;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header&amp;nbsp;Host&amp;nbsp;$http_host;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_redirect&amp;nbsp;off;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_pass&amp;nbsp;http://mongrel;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;=======================&lt;br /&gt;&lt;br /&gt;其實還有一大堆設定我省略掉了，可以自己上官網或 google 找其他的設定。&lt;br /&gt;啟動：&lt;br /&gt;sudo nginx -c config/nginx.conf&lt;br /&gt;關閉：&lt;br /&gt;sudo kill `cat tmp/pids/nginx.pid`&lt;br /&gt;&lt;br /&gt;我用這個去跑 YSlow, 應該是設定的關係，分數從 62 =&gt; 75...&lt;br /&gt;但當然以我測試機的超低流量來看，就算直接用 mongrel 應該也是瞬間反應…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-3279984706941692070?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/3279984706941692070/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=3279984706941692070' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3279984706941692070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3279984706941692070'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/08/fedora-core-6-beast-3.html' title='Fedora Core 6 上安裝 beast (3)'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-7661959315792345009</id><published>2007-08-15T21:09:00.000+08:00</published><updated>2007-08-15T21:16:53.352+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lighttpd'/><category scheme='http://www.blogger.com/atom/ns#' term='安裝'/><category scheme='http://www.blogger.com/atom/ns#' term='pound'/><title type='text'>Fedora Core 6 上安裝 beast (2)</title><content type='html'>不喜歡 apache 嗎？apache 沒辦法用 mod_proxy_balancer 嗎？沒關係，我找到另外一個不錯的方式了，是 pound + lighttpd. 如果不想用 apache 的話，上一篇的 httpd 相關的東西都不要灌，改灌：&lt;br /&gt;&lt;br /&gt;sudo yum install Pound&lt;br /&gt;sudo yum install lighttpd&lt;br /&gt;&lt;br /&gt;我是覺得這邊分大小寫很沒意義，不過 yum 就是這樣﹍。&lt;br /&gt;&lt;br /&gt;pound 是什麼？&lt;br /&gt;The Pound program is a reverse proxy, load balancer and HTTPS front-end for&lt;br /&gt;Web server(s). Pound was developed to enable distributing the load among&lt;br /&gt;several Web-servers and to allow for a convenient SSL wrapper for those&lt;br /&gt;Web servers that do not offer it natively.&lt;br /&gt;&lt;br /&gt;lighttpd 我想大家都知道，一個非常快速的 http server, 只不過他的 mod_proxy 似乎有很多問題，以致於沒辦法用他。所以這部份用 pound 當前端解決這個問題，流程變成：&lt;br /&gt;&lt;br /&gt;http request =&gt; pound =&gt; lighttpd or mongrel cluster&lt;br /&gt;&lt;br /&gt;安裝好後，先來設定 pound, 不過 https 就先暫時略過不管。&lt;br /&gt;sudo nano /etc/pound.cfg&lt;br /&gt;=========================&lt;br /&gt;User "pound"&lt;br /&gt;Group "pound"&lt;br /&gt;&lt;br /&gt;ListenHTTP&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Address&amp;nbsp;0.0.0.0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Port&amp;nbsp;80&lt;br /&gt;End&lt;br /&gt;&lt;br /&gt;Service&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;URL&amp;nbsp;"/(images|stylesheets|javascripts)/"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BackEnd&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Address&amp;nbsp;127.0.0.1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Port&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1999&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Session&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Type&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BASIC&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TTL&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;300&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;br /&gt;End&lt;br /&gt;&lt;br /&gt;Service&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BackEnd&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Address&amp;nbsp;127.0.0.1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Port&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2000&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BackEnd&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Address&amp;nbsp;127.0.0.1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Port&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2001&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BackEnd&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Address&amp;nbsp;127.0.0.1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Port&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2002&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Session&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Type&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BASIC&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TTL&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;300&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;br /&gt;End&lt;br /&gt;=========================&lt;br /&gt;前面的設定是把 host/images, host/stylesheets, host/javascripts 這三個 url 下的 request 都丟給 port 1999 處理，也就是等會 lighttpd 要使用的 port. 這邊使用 regex, 可以自由設定自己要的規則。假使未來 user 要使用 file_column, 可以再加個 user/avatar 之類的。&lt;br /&gt;&lt;br /&gt;下面的則是全部丟給 mongrel_cluster 處理。設定上應該比 apache 簡單地多。可以先測試看看，先把 lighttpd 的部份 comment 起來，啟動 pound 試試：&lt;br /&gt;sudo pound&lt;br /&gt;&lt;br /&gt;照理說這樣就能使用了。不行的話加個 config 檔路徑給他：&lt;br /&gt;sudo pound -f /etc/pound.cfg&lt;br /&gt;&lt;br /&gt;這邊我是在想要不要把 config 也放到 beast 裡面，不過 pound 應該只會有一個，所以我想還是放到 /etc 下好了。停止 pound 的方式：&lt;br /&gt;sudo kill `sudo cat /var/run/pound.pid`&lt;br /&gt;&lt;br /&gt;製作 lighttpd 設定檔：&lt;br /&gt;nano config/lighttpd.conf&lt;br /&gt;==========================&lt;br /&gt;server.modules = ( &lt;br /&gt;  "mod_access",&lt;br /&gt;  "mod_accesslog"&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;server.port = 1999&lt;br /&gt;server.bind = "127.0.0.1"&lt;br /&gt;server.document-root = "/home/YOUR_NAME/projects/beast/stable-1.0/public"&lt;br /&gt;&lt;br /&gt;server.username  = "YOUR_NAME"&lt;br /&gt;server.groupname = "YOUR_NAME"&lt;br /&gt;server.pid-file  = "/home/YOUR_NAME/projects/beast/stable-1.0/tmp/pids/lighttpd.pid" &lt;br /&gt;server.errorlog  = "/home/YOUR_NAME/projects/beast/stable-1.0/log/lighttpd_error.log" &lt;br /&gt;index-file.names = ( "index.html", "default.html" )&lt;br /&gt;accesslog.filename = "/home/YOUR_NAME/projects/beast/stable-1.0/log/lighttpd_access.log"&lt;br /&gt;&lt;br /&gt;# mimetype mapping&lt;br /&gt;mimetype.assign             = (&lt;br /&gt;  ".rpm"          =&gt;      "application/x-rpm",&lt;br /&gt;  ".pdf"          =&gt;      "application/pdf",&lt;br /&gt;  ".sig"          =&gt;      "application/pgp-signature",&lt;br /&gt;  ".spl"          =&gt;      "application/futuresplash",&lt;br /&gt;  ".class"        =&gt;      "application/octet-stream",&lt;br /&gt;  ".ps"           =&gt;      "application/postscript",&lt;br /&gt;  ".torrent"      =&gt;      "application/x-bittorrent",&lt;br /&gt;  ".dvi"          =&gt;      "application/x-dvi",&lt;br /&gt;  ".gz"           =&gt;      "application/x-gzip",&lt;br /&gt;  ".pac"          =&gt;      "application/x-ns-proxy-autoconfig",&lt;br /&gt;  ".swf"          =&gt;      "application/x-shockwave-flash",&lt;br /&gt;  ".tar.gz"       =&gt;      "application/x-tgz",&lt;br /&gt;  ".tgz"          =&gt;      "application/x-tgz",&lt;br /&gt;  ".tar"          =&gt;      "application/x-tar",&lt;br /&gt;  ".zip"          =&gt;      "application/zip",&lt;br /&gt;  ".mp3"          =&gt;      "audio/mpeg",&lt;br /&gt;  ".m3u"          =&gt;      "audio/x-mpegurl",&lt;br /&gt;  ".wma"          =&gt;      "audio/x-ms-wma",&lt;br /&gt;  ".wax"          =&gt;      "audio/x-ms-wax",&lt;br /&gt;  ".ogg"          =&gt;      "application/ogg",&lt;br /&gt;  ".wav"          =&gt;      "audio/x-wav",&lt;br /&gt;  ".gif"          =&gt;      "image/gif",&lt;br /&gt;  ".jpg"          =&gt;      "image/jpeg",&lt;br /&gt;  ".jpeg"         =&gt;      "image/jpeg",&lt;br /&gt;  ".png"          =&gt;      "image/png",&lt;br /&gt;  ".xbm"          =&gt;      "image/x-xbitmap",&lt;br /&gt;  ".xpm"          =&gt;      "image/x-xpixmap",&lt;br /&gt;  ".xwd"          =&gt;      "image/x-xwindowdump",&lt;br /&gt;  ".css"          =&gt;      "text/css",&lt;br /&gt;  ".html"         =&gt;      "text/html",&lt;br /&gt;  ".htm"          =&gt;      "text/html",&lt;br /&gt;  ".js"           =&gt;      "text/javascript",&lt;br /&gt;  ".asc"          =&gt;      "text/plain",&lt;br /&gt;  ".c"            =&gt;      "text/plain",&lt;br /&gt;  ".cpp"          =&gt;      "text/plain",&lt;br /&gt;  ".log"          =&gt;      "text/plain",&lt;br /&gt;  ".conf"         =&gt;      "text/plain",&lt;br /&gt;  ".text"         =&gt;      "text/plain",&lt;br /&gt;  ".txt"          =&gt;      "text/plain",&lt;br /&gt;  ".dtd"          =&gt;      "text/xml",&lt;br /&gt;  ".xml"          =&gt;      "text/xml",&lt;br /&gt;  ".mpeg"         =&gt;      "video/mpeg",&lt;br /&gt;  ".mpg"          =&gt;      "video/mpeg",&lt;br /&gt;  ".mov"          =&gt;      "video/quicktime",&lt;br /&gt;  ".qt"           =&gt;      "video/quicktime",&lt;br /&gt;  ".avi"          =&gt;      "video/x-msvideo",&lt;br /&gt;  ".asf"          =&gt;      "video/x-ms-asf",&lt;br /&gt;  ".asx"          =&gt;      "video/x-ms-asf",&lt;br /&gt;  ".wmv"          =&gt;      "video/x-ms-wmv",&lt;br /&gt;  ".bz2"          =&gt;      "application/x-bzip",&lt;br /&gt;  ".tbz"          =&gt;      "application/x-bzip-compressed-tar",&lt;br /&gt;  ".tar.bz2"      =&gt;      "application/x-bzip-compressed-tar"&lt;br /&gt; )&lt;br /&gt;==========================&lt;br /&gt;我很想省略 mime-type 設定，不過不設的話 firefox 好像會有問題。safari 和 opera 是 ok 的，IE 我沒得測就沒測了。反正要設就是了，有沒有問題不影響。只是希望 lighttpd 能內建這些設定﹍。&lt;br /&gt;&lt;br /&gt;啟動 lighttpd&lt;br /&gt;sudo lighttpd -f config/lighttpd.conf&lt;br /&gt;&lt;br /&gt;這樣就算大功告成了！剛剛有測試 pound 的話記得改回原本設定並重新啟動。比較詳細的介紹與說明可以參考這篇：&lt;br /&gt;&lt;a href="http://www.aidanf.net/rails/configuring-pound-with-lighttpd-and-mongrel" target="_blank"&gt;Configuring pound with lighttpd and mongrel.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;*&lt;br /&gt;&lt;br /&gt;summary:&lt;br /&gt;&lt;br /&gt;用到的 server:&lt;br /&gt;&lt;br /&gt;(1)&lt;br /&gt;apache2.2 =&gt;&lt;br /&gt;reverse proxy + load balancer + serve static files&lt;br /&gt;&lt;br /&gt;(2)&lt;br /&gt;pound =&gt; reverse proxy + load balancer&lt;br /&gt;lighttpd =&gt; serve static files&lt;br /&gt;&lt;br /&gt;(3)&lt;br /&gt;mongrel_cluster =&gt; setup mongrel cluster&lt;br /&gt;mongrel =&gt; serve beast&lt;br /&gt;&lt;br /&gt;結果就是 ((1) or (2)) + (3)&lt;br /&gt;&lt;br /&gt;操作 apache:&lt;br /&gt;啟動：sudo apachectl start&lt;br /&gt;停止：sudo apachectl stop&lt;br /&gt;重啟：sudo apachectl restart&lt;br /&gt;&lt;br /&gt;操作 pound:&lt;br /&gt;啟動：sudo pound -f /etc/pound.cfg&lt;br /&gt;　或：sudo /etc/init.d/pound start&lt;br /&gt;&lt;br /&gt;停止：sudo kill `sudo cat /var/run/pound.pid`&lt;br /&gt;　或：sudo /etc/init.d/pound stop&lt;br /&gt;&lt;br /&gt;重啟：sudo /etc/init.d/pound restart&lt;br /&gt;&lt;br /&gt;操作 lighttpd:&lt;br /&gt;啟動：sudo lighttpd -f config/lighttpd.conf&lt;br /&gt;　或：sudo /etc/init.d/lighttpd start&lt;br /&gt;&lt;br /&gt;停止：sudo kill `cat tmp/pids/lighttpd.pid`&lt;br /&gt;　或：sudo /etc/init.d/lighttpd stop&lt;br /&gt;&lt;br /&gt;重啟：sudo /etc/init.d/lighttpd restart&lt;br /&gt;&lt;br /&gt;操作 mongrel_cluster:&lt;br /&gt;啟動：sudo mongrel_rails cluster::start&lt;br /&gt;停止：sudo mongrel_rails cluster::stop&lt;br /&gt;重啟：sudo mongrel_rails cluster::restart&lt;br /&gt;&lt;br /&gt;操作 postgresql:&lt;br /&gt;啟動：sudo pg_ctl start&lt;br /&gt;停止：sudo pg_ctl stop&lt;br /&gt;重啟：sudo pg_ctl restart&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7661959315792345009?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/7661959315792345009/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=7661959315792345009' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7661959315792345009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7661959315792345009'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/08/fedora-core-6-beast-2.html' title='Fedora Core 6 上安裝 beast (2)'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-7721295741834952547</id><published>2007-08-14T12:04:00.000+08:00</published><updated>2007-08-15T13:07:27.133+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mongrel'/><category scheme='http://www.blogger.com/atom/ns#' term='beast'/><category scheme='http://www.blogger.com/atom/ns#' term='安裝'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>Fedora Core 6 上安裝 beast</title><content type='html'>我選擇 apache2.2 + mongrel_cluster + postgresql&lt;br /&gt;&lt;br /&gt;安裝 apache 和其他的東西。&lt;br /&gt;sudo yum install httpd&lt;br /&gt;sudo yum install httpd-devel&lt;br /&gt;sudo yum install openssl&lt;br /&gt;sudo yum install readline&lt;br /&gt;&lt;br /&gt;安裝 ruby&lt;br /&gt;sudo yum install ruby&lt;br /&gt;sudo yum install ruby-devel&lt;br /&gt;sudo yum install ruby-libs&lt;br /&gt;sudo yum install rdoc&lt;br /&gt;sudo yum install irb&lt;br /&gt;&lt;br /&gt;安裝 postgresql&lt;br /&gt;sudo yum install postgresql&lt;br /&gt;sudo yum install postgresql-devel&lt;br /&gt;sudo yum install postgresql-libs&lt;br /&gt;sudo yum install postgresql-server&lt;br /&gt;&lt;br /&gt;初始化 postgres&lt;br /&gt;sudo mkdir -p /var/db/postgresql81/defaultdb&lt;br /&gt;sudo chown postgres:postgres /var/db/postgresql81/defaultdb&lt;br /&gt;sudo -u postgres initdb -D /var/db/postgresql81/defaultdb&lt;br /&gt;sudo -u postgres pg_ctl -D /var/db/postgresql81/defaultdb \&lt;br /&gt;-l /var/db/postgresql81/defaultdb/postgres.log start&lt;br /&gt;&lt;br /&gt;拿來抓 beast... 捨 svn 取 svk 因為我討厭一堆 .svn&lt;br /&gt;sudo yum install perl-SVK&lt;br /&gt;&lt;br /&gt;sudo yum install rubygems&lt;br /&gt;&lt;br /&gt;至少要用這些 gem&lt;br /&gt;sudo gem install rails -y&lt;br /&gt;sudo gem install mongrel_cluster -y&lt;br /&gt;sudo gem install redcloth -y&lt;br /&gt;sudo gem install ruby-openid -y&lt;br /&gt;sudo gem install ruby-postgres -y&lt;br /&gt;&lt;br /&gt;建立目錄。&lt;br /&gt;mkdir -p ~/projects/beast&lt;br /&gt;cd ~/projects/beast&lt;br /&gt;&lt;br /&gt;用 svk 抓不會有一堆 .svn 礙眼。&lt;br /&gt;svk mirror //mirror/beast \&lt;br /&gt;http://svn.techno-weenie.net/projects/beast/branches/stable-1.0/&lt;br /&gt;svk sync -s HEAD //mirror/beast&lt;br /&gt;cd stable-1.0&lt;br /&gt;&lt;br /&gt;產生讓 beast 用的資料庫。&lt;br /&gt;sudo -u postgres createdb beast_prod&lt;br /&gt;&lt;br /&gt;設定資料庫設定檔。&lt;br /&gt;cp config/database.example.yml config/database.yml&lt;br /&gt;&lt;br /&gt;nano config/database.yml&lt;br /&gt;=========================&lt;br /&gt;production:&lt;br /&gt;&amp;nbsp;&amp;nbsp;database: beast_prod&lt;br /&gt;&amp;nbsp;&amp;nbsp;adapter: postgresql&lt;br /&gt;&amp;nbsp;&amp;nbsp;host: localhost&lt;br /&gt;&amp;nbsp;&amp;nbsp;username: postgres&lt;br /&gt;&amp;nbsp;&amp;nbsp;password:&lt;br /&gt;=========================&lt;br /&gt;&lt;br /&gt;初始化 beast 資料庫。&lt;br /&gt;rake db:schema:load RAILS_ENV=production&lt;br /&gt;&lt;br /&gt;非常囉唆的 cluster 設定，user 可以開 mongrel,&lt;br /&gt;不過因為我懶所以用自己的帳號跑。&lt;br /&gt;sudo mongrel_rails cluster::configure -e production \&lt;br /&gt;-p 2000 -N 3 -c /home/YOUR_NAME/projects/beast/stable-1.0 \&lt;br /&gt;-a 127.0.0.1 --user YOUR_NAME --group YOUR_NAME&lt;br /&gt;&lt;br /&gt;啟動 mongrel_cluster 吧。&lt;br /&gt;sudo mongrel_rails cluster::start&lt;br /&gt;&lt;br /&gt;接著是 apache2.2 的 mod_proxy_balancer 的設定，&lt;br /&gt;如果 mod_proxy_balancer 沒有啟動記得把他打開。&lt;br /&gt;&lt;br /&gt;建立 balancer 導向 port 2000~2002&lt;br /&gt;sudo nano /etc/httpd/conf/httpd.conf&lt;br /&gt;=====================================&lt;br /&gt;&amp;lt;Proxy balancer://YOUR_BALANCER&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;BalancerMember http://YOUR_ADDRESS:2000&lt;br /&gt;&amp;nbsp;&amp;nbsp;BalancerMember http://YOUR_ADDRESS:2001&lt;br /&gt;&amp;nbsp;&amp;nbsp;BalancerMember http://YOUR_ADDRESS:2002&lt;br /&gt;&amp;lt;/Proxy&amp;gt;&lt;br /&gt;&lt;br /&gt;Listen 80&lt;br /&gt;&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;ServerAdmin YOUR_EMAIL&lt;br /&gt;&amp;nbsp;&amp;nbsp;ServerName YOUR_ADDRESS&lt;br /&gt;&amp;nbsp;&amp;nbsp;ProxyPass / balancer://YOUR_BALANCER/&lt;br /&gt;&amp;nbsp;&amp;nbsp;ProxyPassReverse / balancer://YOUR_BALANCER/&lt;br /&gt;&amp;nbsp;&amp;nbsp;ProxyPreserveHost on&lt;br /&gt;&amp;nbsp;&amp;nbsp;ErrorLog /home/YOUR_NAME/projects/beast/stable-1.0/log/apache_error.log&lt;br /&gt;&amp;nbsp;&amp;nbsp;CustomLog /home/YOUR_NAME/projects/beast/stable-1.0/log/apache_access.log combined&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;ProxyPass /images !&lt;br /&gt;&amp;nbsp;&amp;nbsp;ProxyPass /stylesheets !&lt;br /&gt;&amp;nbsp;&amp;nbsp;ProxyPass /javascripts !&lt;br /&gt;&amp;nbsp;&amp;nbsp;Alias /images /home/YOUR_NAME/projects/beast/stable-1.0/public/images&lt;br /&gt;&amp;nbsp;&amp;nbsp;Alias /stylesheets /home/YOUR_NAME/projects/beast/stable-1.0/public/stylesheets&lt;br /&gt;&amp;nbsp;&amp;nbsp;Alias /javascripts /home/YOUR_NAME/projects/beast/stable-1.0/public/javascripts&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;=====================================&lt;br /&gt;&lt;br /&gt;接著啟動 apache 就 ok 了。&lt;br /&gt;sudo apachectl start&lt;br /&gt;&lt;br /&gt;最後來設定 beast 的 smtp, 如果想用 gmail 寄信的話，&lt;br /&gt;我之前試過兩個方式，一個是使用 msmtp,&lt;br /&gt;另一個是有人有寫一小段 ssl smtp 的 patch, 可以參考這裡：&lt;br /&gt;&lt;a href="http://www.stephenchu.com/2006/06/how-to-use-gmail-smtp-server-to-send.html"&gt;http://www.stephenchu.com/2006/06/how-to-use-gmail-smtp-server-to-send.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;nano config/environment.rb&lt;br /&gt;加入：&lt;br /&gt;===========================&lt;br /&gt;ActionMailer::Base.smtp_settings = {&lt;br /&gt;&amp;nbsp;&amp;nbsp;:address =&gt; "smtp.gmail.com",&lt;br /&gt;&amp;nbsp;&amp;nbsp;:port =&gt; 587, &lt;br /&gt;&amp;nbsp;&amp;nbsp;:domain =&gt; 'YOUR_DOMAIN',&lt;br /&gt;&amp;nbsp;&amp;nbsp;:user_name =&gt; "YOUR_GMAIL_ACCOUNT",&lt;br /&gt;&amp;nbsp;&amp;nbsp;:password =&gt; 'YOUR_GMAIL_PASSWORD',&lt;br /&gt;&amp;nbsp;&amp;nbsp;:authentication =&gt; :plain&lt;br /&gt;}&lt;br /&gt;===========================&lt;br /&gt;&lt;br /&gt;nano app/models/user_mailer.rb&lt;br /&gt;===============================&lt;br /&gt;@from = 'YOUR_GMAIL_ACCOUNT@gmail.com'&lt;br /&gt;===============================&lt;br /&gt;我不是很確定這一步要不要做，我猜不做會被 gamil 擋掉。&lt;br /&gt;&lt;br /&gt;接下來把那段程式碼 copy 到可以被 require 的地方，我是放在 lib 下：&lt;br /&gt;nano lib/smtp_tls.rb&lt;br /&gt;接著把他 require 進去：&lt;br /&gt;nano config/environment.rb&lt;br /&gt;===========================&lt;br /&gt;require 'smtp_tls'&lt;br /&gt;===========================&lt;br /&gt;&lt;br /&gt;sudo mongrel_rails cluster::restart&lt;br /&gt;註冊一下試試寄信吧！如果失敗的話，那篇連結裡有個 workaround:&lt;br /&gt;&lt;br /&gt;nano lib/smtp_tls.rb&lt;br /&gt;=====================&lt;br /&gt;rescue EOFError&lt;br /&gt;&amp;nbsp;&amp;nbsp;;&lt;br /&gt;rescue OpenSSL::SSL::SSLError =&gt; e&lt;br /&gt;&amp;nbsp;&amp;nbsp;puts('Unexpected Exception: ' + e.message + ' : ' +&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.backtrace.join("\n") )&lt;br /&gt;end&lt;br /&gt;=====================&lt;br /&gt;&lt;br /&gt;我之前用是沒有這個問題，但在這台 fedora 上卻有這個問題，&lt;br /&gt;也許是要更新 openssl 的版本？不管如何，加入上面那段暫時可用。&lt;br /&gt;&lt;br /&gt;結論：&lt;br /&gt;還是 macports 好用，速度快，更新快，只是 build 要很久就是了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7721295741834952547?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/7721295741834952547/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=7721295741834952547' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7721295741834952547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7721295741834952547'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/08/fedora-core-6-beast.html' title='Fedora Core 6 上安裝 beast'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-189631188805797796</id><published>2007-08-13T00:57:00.000+08:00</published><updated>2007-08-13T01:00:06.671+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='functional'/><title type='text'>ludy 0.0.4 released</title><content type='html'>花了一點時間再測試了一下 curry 的實做，i am glad to announce that ludy 0.0.4 is released. 原本的 Proc#curry 被改名為 Proc#__curry__, 我很想把他&lt;br /&gt;deprecate 掉，但是後來的 Kernel#curry 也有運用到該實做，是有在考慮把他從 public 改到 private, 但考慮到也許還有用處，還是暫時放在 public 下，以後如果發現真的沒用了，會改到 private 下。&lt;br /&gt;&lt;br /&gt;現在的用法是：&lt;br /&gt;&lt;br /&gt;multiply = lambda{|l,r| l*r}&lt;br /&gt;&lt;br /&gt;double = multiply.curry[2]&lt;br /&gt;assert_equal 8, double[4]&lt;br /&gt;assert_equal 6, double[3]&lt;br /&gt;&lt;br /&gt;xd = multiply['XD', 5]&lt;br /&gt;assert_equal 'XDXDXDXDXD', xd&lt;br /&gt;&lt;br /&gt;assert_equal 29, :+.to_proc.curry[18][11]&lt;br /&gt;assert_equal (0..4).to_a, lambda{|a,b,c,d,e|[a,b,c,d,e]}.curry[0][1][2][3][4]&lt;br /&gt;&lt;br /&gt;只要呼叫到了 Kernel#curry, 且 caller 本身回應（respond_to?）:call 和 :[], 則回傳一個 curry function, 這樣就可以有更強的 consistency, 不需要注意什麼時候使用 () 而什麼時候使用 [], 請一律使用 function call/[], 不用擔心參數是否足夠，足夠時就會回傳真正的答案，否則再度傳回 curry function.&lt;br /&gt;&lt;br /&gt;所以其實我是在想，以下兩者是否相同？&lt;br /&gt;class Array; include Curry; end&lt;br /&gt;func1 = [].cfoldr&lt;br /&gt;func2 = [].method(:foldr).curry&lt;br /&gt;func1 == func2 # =&gt; true? or false?&lt;br /&gt;&lt;br /&gt;我的希望是相同，當然。只是我直接換上這樣的實做似乎有點問題，這個狀況可能在 0.0.5 中解決，使 curry module 和 kernel#curry 也能夠擁有該有的一致性。&lt;br /&gt;&lt;br /&gt;另一個棘手問題是 ruby 的 block, 乍看很好用，實際上也是，但是卻造成了很大的不一致。這一點也真的是很難搞定，之前的 this 就有碰上這樣的大問題，使用 yield 似乎無法產生正確的 call stack.&lt;br /&gt;&lt;br /&gt;*&lt;br /&gt;&lt;br /&gt;最後則是 0.0.4 上的實做問題，由於 :*.to_proc 的這個 proc 無法預測其正確的 arity, 就像 :message_that_you_never_know.to_proc 也不可能能知道他的 arity 是多少一樣，這造成了難以判斷何時該回傳正確的值而非另一個 curry function. 我是想要從 Symbol#to_proc 去竄改，不過這會碰上另外兩個問題：&lt;br /&gt;&lt;br /&gt;1. 會跟其他人的實做衝突&lt;br /&gt;2. caller 和 arity 是合併在一起的，意味還沒 call 之前都不會知道 arity, 這樣我就沒辦法強迫 Symbol#to_proc 能產生正確的 arity.&lt;br /&gt;&lt;br /&gt;所以我只好用另外一個很愚蠢的方式：trial &amp; error.&lt;br /&gt;begin # let's try if arguments are ready&lt;br /&gt;&amp;nbsp;&amp;nbsp;self.__send__ :orig_call, *args, &amp;block&lt;br /&gt;rescue ArgumentError # oops, let's curry it&lt;br /&gt;&amp;nbsp;&amp;nbsp;method(:call).to_proc.__send__ :__curry__, *args&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;效率問題就別提了，我真的覺得這樣很蠢，可是好像也想不到更好的方式。&lt;br /&gt;&lt;br /&gt;所以 0.0.4 就只暫時強化了 curry 的實做，離完善還有很大的一段距離。雖然心血來潮度極高，但好像還算有進展？&lt;br /&gt;&lt;br /&gt;gem install ludy&lt;br /&gt;to see detail.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-189631188805797796?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/189631188805797796/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=189631188805797796' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/189631188805797796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/189631188805797796'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/08/ludy-004-released.html' title='ludy 0.0.4 released'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-6791629758620526949</id><published>2007-08-07T14:04:00.000+08:00</published><updated>2007-08-07T14:09:16.211+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='functional'/><title type='text'>ludy 0.0.3 released</title><content type='html'>睽違已久，忽然心血來潮多加了幾個東西。&lt;br /&gt;in CHANGES:&lt;br /&gt;==============================&lt;br /&gt;ludy 0.0.3, 2007.08.07&lt;br /&gt;&lt;br /&gt;1. ludy_ext:&lt;br /&gt;  added:&lt;br /&gt;    1. Proc#curry&lt;br /&gt;    2. Proc#compose&lt;br /&gt;    3. Proc#chain&lt;br /&gt;    4. Symbol#to_proc&lt;br /&gt;    5. Array#foldl&lt;br /&gt;    6. Array#foldr&lt;br /&gt;    7. Array#filter&lt;br /&gt;&lt;br /&gt;  removed:&lt;br /&gt;    1. Fixnum#collect # see tc_ludy_ext.rb#test_fixnum_collect for reason&lt;br /&gt;&lt;br /&gt;  info:&lt;br /&gt;    1. ruby2ruby has NilClass#method_missing return nil,&lt;br /&gt;       so i can't just make it return blackhole&lt;br /&gt;&lt;br /&gt;2. module Curry:&lt;br /&gt;  see test/tc_curry.rb for usage&lt;br /&gt;&lt;br /&gt;see unit test for usage&lt;br /&gt;==============================&lt;br /&gt;雖然說請看 unit test 來揣摩用法，不過這樣真的有點無趣，所以還是來稍微介紹一下。這次之所以忽然心血來潮想做，是因為看到James Edward Gray II 的 higher-order ruby 專欄：&lt;br /&gt;&lt;a href="http://blog.grayproductions.net/articles/category/higher-order-ruby" target="_blank"&gt;http://blog.grayproductions.net/articles/category/higher-order-ruby&lt;/a&gt;&lt;br /&gt;第六篇的：Currying, 他的 curry 實做：&lt;br /&gt;&lt;pre&gt;class Proc&lt;br /&gt;  def curry(&amp;args_munger)&lt;br /&gt;    lambda { |*args| call(*args_munger[args]) }&lt;br /&gt;  end&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;老實講，不是說看不懂，可是我不明白為什麼要寫得那麼複雜，乍看之下實在看不太出來。丟掉他的實做，我試著做了一個：&lt;br /&gt;&lt;pre&gt;class Proc&lt;br /&gt;  def curry *pre&lt;br /&gt;    lambda{ |*post| self[*(pre + post)] }&lt;br /&gt;  end&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;就我自己測試起來，效果是一樣的，我認為應該簡潔易懂多了。可是這根本不太像 curried function 吧？內心吶喊著。不過在看我後來寫的 curry module 之前，先來簡單介紹一下 currying.&lt;br /&gt;&lt;br /&gt;在 lambda caculus 中，每個 function 都只能有一個 argument, 這是因為 lambda caculus 是一種極簡的語言，用來研究某些模型的語言。但是如果 function 只能吃一個 argument, 有很多事是會做不到的。於是我們可以靠著 tuple 把許多的 argument 包成一個 argument, 例如在 Haskell 中，tuple 就是 (1,2,3), 用括號括起來的就是 tuple. 所以上面的 (1,2,3) 是一個有三個值的 tuple, 可以把他視為一個值。&lt;br /&gt;&lt;br /&gt;比方說有個 function 叫 power, 像是：power 2, 10 會回傳 1024. uncurried function 就會是 power (2, 10), 他吃一個有兩個元素的 tuple, 吐出一個 1024 的值。可是如果是這樣使用的話，其實是很不方便的。有一個方法可以讓 function 依然只吃一個 argument, 但是又不需要使用 tuple, 可以一個值一個值傳入，那就是 curried function.&lt;br /&gt;&lt;br /&gt;在 functional programming 中，function 的地位極高，不管在做什麼事，幾乎都是在操作 function. 這也就是所謂的 higher-order function, 操作 function 的 function, 或是產生 function 的 function 諸如此類。curried function 的效果就是當所吃入的 argument 不足時，他會再吐出另一個 function 去吃其他 argument，直到 argument 足夠時才會吐出結果。&lt;br /&gt;&lt;br /&gt;power 2 的回傳會是一個 function, 他記住了 2, 當他再吃一個 argument 後，則會再把 2 拿出來跟 argument 做運算。所以 power 的 type 會是：&lt;br /&gt;power :: Int -&gt; Int -&gt; Int&lt;br /&gt;結合順序是從右邊開始，所以是吃一個 Int, 吐出 (Int -&gt; Int), 也就是吃一個 Int 吐出一個 Int 的 function. 可以想成這樣：&lt;br /&gt;&lt;br /&gt;power2 = power 2&lt;br /&gt;result = power2 10&lt;br /&gt;result # =&gt; 1024&lt;br /&gt;&lt;br /&gt;也就是說，可以把他看成是一個會不斷記憶 argument 的 function. 看看 James Edward Gray II 的範例：&lt;br /&gt;&lt;pre&gt;multiply = lambda { |l, r| l * r }&lt;br /&gt;double   = multiply.curry { |args| args + [2] }&lt;br /&gt;triple   = multiply.curry { |args| args &lt;&lt; 3 }&lt;br /&gt;&lt;br /&gt;multiply[5, 2]    # =&gt; 10&lt;br /&gt;double[5]         # =&gt; 10&lt;br /&gt;triple[5]         # =&gt; 15&lt;br /&gt;triple["Howdy "]  # =&gt; "Howdy Howdy Howdy "&lt;/pre&gt;&lt;br /&gt;所以他的實做其實很簡單，就是用一個 array 記憶 arguments,&lt;br /&gt;最後再 prepend 到最後的 arguments 裡。&lt;br /&gt;&lt;pre&gt;class Proc&lt;br /&gt;  def curry(&amp;args_munger)&lt;br /&gt;    lambda { |*args| call(*args_munger[args]) }&lt;br /&gt;  end&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;不過我覺得不用寫得那麼複雜，所以改寫為：&lt;br /&gt;&lt;pre&gt;class Proc&lt;br /&gt;  def curry *pre&lt;br /&gt;    lambda{ |*post| self[*(pre + post)] }&lt;br /&gt;  end&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;這裡利用了 ruby 的 lambda 有 closure 的特性，把 *pre 紀錄下來，再把他 prepend 到 post 上，最後再呼叫原本的自己（self）。&lt;br /&gt;&lt;br /&gt;可是這樣不完整，因為你必須明確表達你需要做 curry, 而 Haskell 的 curried function 是可以讓你忽略這件事的。&lt;br /&gt;&lt;br /&gt;lambda{|a,b,c,d,e|}.curry(1).curry(2).curry(3).curry(4).carry(5)&lt;br /&gt;&lt;br /&gt;這樣不煩死才怪。我希望能用：&lt;br /&gt;&lt;br /&gt;lambda{|a,b,c,d,e|}[1][2][3][4][5]&lt;br /&gt;也能使用：&lt;br /&gt;lambda{|a,b,c,d,e|}[1,2][3][4,5]&lt;br /&gt;&lt;br /&gt;可惜我暫時還沒找到好做法 XD 目前暫時僅提供可以 mixin 的 module, 大概是這樣用：&lt;br /&gt;&lt;br /&gt;class Array; include Curry; end&lt;br /&gt;&lt;br /&gt;接著 array 所有以字母開頭的 method 會多個 curried 版，prefix c. i.e., map =&gt; cmap; foldr =&gt; cfoldr&lt;br /&gt;&lt;br /&gt;func1 = [1,2,3].cfoldr[:-.to_proc]&lt;br /&gt;assert_equal 2, func1[0]&lt;br /&gt;&lt;br /&gt;做法其實很簡單，就只是檢查參數夠了沒，不夠就重新 curry 一份，夠了就呼叫原始 method. 我原本一直不希望前綴 c, 而以相同名字命名之，然後原本的名字改為：orig_method. 可惜不管怎麼試都失敗，原因不是很清楚，但這種 side-effect 超大的動作，會失敗其實也不怎麼奇怪吧，我想。雖然我總覺得以正常呼叫法而言，應該是沒什麼差才對，也許我有哪裡寫錯了，只是還沒發現而已。&lt;br /&gt;&lt;br /&gt;*&lt;br /&gt;&lt;br /&gt;至於其他新增的東西，這裡也稍微介紹一下。首先 Array#filter 只是 select 的 alias, Array#foldl 也只是 inject 的 wrapper. Array#foldr 稍微複雜些，不過概念上只是類似反過來的 inject 而已。Symbol#to_proc 大家應該都很熟，連 active_support 裡面也有。只是單純的 message/method 轉換而已。&lt;br /&gt;&lt;br /&gt;比較需要提的應該是 Proc#compose 和 Proc#chain. 前者就是數學上的 compose, facets 裡其實也有，不過手癢還是自己做了一份。他有點類似反向的 inject, 很容易做出來。至於 chain, 這是模仿 C++ 的 loki 中的 functor 中的 chain. 效果很單純，就是把 function 串起來而已。這拿來做 callback 應該還算方便，例如：&lt;br /&gt;&lt;br /&gt;button.on_click = menu.method(:popup).chain button.method(:hide)&lt;br /&gt;接著當按鈕被按下去後，選單就會彈出，且按鈕自動隱藏。&lt;br /&gt;至於 arguments 和 returns 呢？arguments 會統一給所有人。&lt;br /&gt;f1.chain(f2)['XD']&lt;br /&gt;這樣 f1 和 f2 都會接到 'XD' 這個 argument. return 則會蒐集成一個 array 並 flatten 回去。&lt;br /&gt;[f1 的結果, f2 的結果, f3 的結果,...]&lt;br /&gt;如果 f3 的結果是 array, 則會依序儲存：&lt;br /&gt;[..., f3 的結果1, f3 的結果2, f4 的結果, ...]&lt;br /&gt;&lt;br /&gt;這樣做的原因是要讓 chain 還能繼續 chain 而不會出現非常恐怖的 nested array.&lt;br /&gt;f1.chain(f2).chain(f3).chain(f4)&lt;br /&gt;但是其實可以這樣 chain:&lt;br /&gt;f1.chain(f2, f3, f4)&lt;br /&gt;結果和上面的會是相同的。&lt;br /&gt;&lt;br /&gt;在 chain 之間的 travel 還沒做，下次有機會時會做。&lt;br /&gt;&lt;br /&gt;gem install ludy # to see detail&lt;br /&gt;&lt;br /&gt;ruby 寫起來真的很簡潔，很多功能 10 行內都能解決。&lt;br /&gt;&lt;br /&gt;2007.08.07&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6791629758620526949?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/6791629758620526949/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=6791629758620526949' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6791629758620526949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6791629758620526949'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/08/ludy-003-released.html' title='ludy 0.0.3 released'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-4765567148374134820</id><published>2007-07-28T00:31:00.000+08:00</published><updated>2007-07-28T00:36:10.223+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Active Scaffold Upload Branch</title><content type='html'>我真的被 rails plugin 嚇到了。這幾天試著做 web development, 大家應該都知道我跟這個領域不太熟吧？可是，忽然間我覺得，這樣幾乎什麼都能做了。三個 plugin, 依照我嘗試的時間順序：&lt;br /&gt;&lt;br /&gt;1. &lt;a href="http://www.kanthak.net/opensource/file_column/" target="_blank"&gt;FileColumn&lt;/a&gt;&lt;br /&gt;2. &lt;a href="http://wiki.rubyonrails.org/rails/pages/LoginGenerator" target="_blank"&gt;LoginGenerator&lt;/a&gt;&lt;br /&gt;3. &lt;a href="http://wiki.activescaffold.com/wiki/show/Active+Scaffold+Upload+Branch" target="_blank"&gt;Active Scaffold Upload Branch&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;由於一開始使用 FileColumn 碰到了點問題，所以我有稍微 trace 他的 code, 基本上這個 plugin 我覺得算是小玩具，很簡單的小功能，居然沒內建到 rails 中我覺得有點奇怪。畢竟 binary file 一般都是存到 file system 而非 db 中吧？搭配 rmagick 的感覺還算不錯，可惜 helper 似乎不太健全，雖然堪用了。&lt;br /&gt;&lt;br /&gt;接下來碰到需要 auth 的部份，懶得自己寫，因為只是小地方需要，並不真正屬於我目前所要寫的東西的一部份。重新發明輪子我覺得不是問題，但如果只是想到旁邊的便利商店買罐飲料卻因此得重新發明輪子，呃，這是成本考量與優先序的問題啊。&lt;br /&gt;&lt;br /&gt;於是試了一下 LoginGenerator, 發現﹍。嗯，還真的是很方便。雖然他是個 gem, 但是 generate 出來之後就沒有 dependency 了，而且要自己改什麼也都很容易。於是 auth 的部份也解決了，畢竟我只是要最簡單的 auth.（雖然他安全性做得如何我就不清楚了，沒有仔細看他的程式碼）&lt;br /&gt;&lt;br /&gt;到這裡，我都還不覺得怎麼樣。第三個 ActiveScaffold 就真的嚇到我了。因為那真的是非常完整的實做。rails 內建的 scaffold 實在陽春過頭，（儘管陽春過頭了，第一次看到還是著實相當驚豔，現在有種鄉巴佬進城的感覺）除非是最簡單的資料，不然碰上 association 或是 file column, 全部都沒辦法應付。當然，我是可以自己去改自己去擴充，但同樣是成本與優先序的問題，一定得需要用別人的東西。&lt;br /&gt;&lt;br /&gt;先是找到了 scaffold extensions, 其實我是比較欣賞這種模式。不要產生一堆程式碼，要改什麼，利用 ruby 的 dynamic 機制就好了。只是他文件實在不多，看來看去要擴充好像還滿有難度的，而且雖然號稱支援 association, 卻是﹍。我只能說真的很難用，不過是多個 link 出來罷了，是比沒有好啦，但是應該會邊用邊想打人吧？&lt;br /&gt;&lt;br /&gt;接下來我乾脆直接 google file column + scaffold 算了。就找到了 Active Scaffold Upload Branch, which is evolved from ajax scaffold. 他的 file column 範例，呃，問題一大堆，有些根本就寫錯了，害我試半天試不出來，有點火大。想說調查一下他的 form 到底是怎麼回事，卻發現他居然整個是用 ajax 寫的，所以 rails 有錯誤不見得會回傳，而且 form 也因為動態產生而無法顯示！&lt;br /&gt;&lt;br /&gt;幸好有 firefox 的 web developer 這個 add-on, 裝了很久卻很少在用，帶有僥倖的心情找了一下，發現他的 display 功能非常強大，舉凡頁面上出得來的，全部都能顯示。然後才發現，active scaffold 額外產生了一個 record 去存，這樣的話下面這一行就明顯不正確了！&lt;br /&gt;&lt;%= file_column_field 'entry', 'file' %&gt;&lt;br /&gt;我還是頭一次看到範例有這麼嚴重錯誤的，太相信他結果找錯誤找半天。:( 害我又一直懷疑到 file column 和 rmagick 上，看半天覺得應該沒錯才對。而且這一個 method 也不知道是幹嘛的：&lt;br /&gt;　def file_form_column(record, input_name)&lt;br /&gt;　　file_column_field 'record', :file&lt;br /&gt;　end&lt;br /&gt;不是明明就有 partial 了嗎？還是這可以取代 partial? 存疑，不管了。&lt;br /&gt;&lt;br /&gt;總而言之，現在不只是 file column 的 image upload 沒問題，要自訂欄位也沒問題，版面上又相當漂亮，不會因為拉扯而變形，排序、搜尋等等，也都相當不錯。最重要的是，他的 association 模式跟我所需要的幾乎完全一致！可以同步修改，可以隱藏，可以追加，所有基本功能似乎都有了。&lt;br /&gt;&lt;br /&gt;本來昏昏欲睡的我，看到這邊實在是很興奮，這東西就算要直接拿來用，都夠格了。而且我相信有什麼不足的話，要修改也容易得很。這有一大半要感謝 Ruby :)&lt;br /&gt;&lt;br /&gt;老實講，我真想知道硬幹派的 php programmer 看到這些會有什麼想法。一個 phpBB 我看隨便寫一寫說不定就跑出來了﹍。搞不好再過不久，寫網站就真的是只要呼叫 =&gt; 修改 =&gt; 呼叫 =&gt; 修改就結束了。這還真的是很恐怖的一件事。不過同時這也代表著，我們應該把眼光放遠點了。來做個 YouOS 吧！！ XD&lt;br /&gt;&lt;br /&gt;==&lt;br /&gt;&lt;br /&gt;最後我還想講一件事，就是寫程式寫這麼久，從來沒碰過幾次時程預估是太長的。但寫 rails 這兩次，很明顯我都估太長了。而且縮短的程度也是非常的多！我想除了要感謝 library 的強大外，雖然我還沒引進 unit test, 只用了人工 test, debug 難度就已經沒有很高了，大部份的錯誤都不會很難抓。當然，這有一個很大的原因是我現在在寫的東西難度很低，可是在這麼不熟悉的情況下，我覺得能夠這樣就真的是非常厲害的了。&lt;br /&gt;&lt;br /&gt;另一方面其實我是覺得寫 Flash 有趣得多，難度也高得多。但 Flash debug 真的是會讓人想抓狂的一件事﹍。不知道有沒有什麼好用的 debug tool? 不然寫 Flash 永遠進度落後實在是很煩。&lt;br /&gt;&lt;br /&gt;==&lt;br /&gt;&lt;br /&gt;script/plugin install http://opensvn.csie.org/rails_file_column/plugins/file_column/trunk&lt;br /&gt;&lt;br /&gt;gem install login_generator&lt;br /&gt;script/generate login&lt;br /&gt;&lt;br /&gt;svn export http://activescaffold.googlecode.com/svn/branches/upload vendor/plugins/active_scaffold_upload&lt;br /&gt;&lt;br /&gt;有時候真不知道用 rubygems 好還是 rails plugin 好，但我想比較不穩定的東西，用後者應該是會好很多吧？self contained 這種事，有時候還滿重要的。&lt;br /&gt;&lt;br /&gt;鄉巴佬全文完。&lt;br /&gt;&lt;br /&gt;2007.07.28&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4765567148374134820?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/4765567148374134820/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=4765567148374134820' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4765567148374134820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4765567148374134820'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/07/active-scaffold-upload-branch.html' title='Active Scaffold Upload Branch'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-959331202414590505</id><published>2007-07-25T22:33:00.000+08:00</published><updated>2007-07-25T22:37:42.336+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='gui'/><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>[心得] RubyCocoa</title><content type='html'>轉自 ptt MacDev 板&lt;br /&gt;&lt;br /&gt;作者 godfat (godfat 真常) 看板  MacDev&lt;br /&gt;標題 [心得] RubyCocoa&lt;br /&gt;時間 Tue Jul 24 21:40:20 2007&lt;br /&gt;──────────────────&lt;br /&gt;&lt;br /&gt;嫌 objective-c 太難用嗎？還在等 obj-c 2.0 嗎？先試試 RubyCocoa 吧 XD&lt;br /&gt;http://rubycocoa.sourceforge.net/&lt;br /&gt;&lt;br /&gt;[quote]&lt;br /&gt;It lets you write full-stack Cocoa applications in Ruby. It is also possible to write a Cocoa application that mixes Ruby and Objective-C code.&lt;br /&gt;[/quote]&lt;br /&gt;&lt;br /&gt;how to install?&lt;br /&gt;有灌 macports 的話：（當然，xcode 是一定要灌的）&lt;br /&gt;sudo port install ruby&lt;br /&gt;sudo port install rb-rubygems（非必要，但建議）&lt;br /&gt;sudo port install rb-cocoa&lt;br /&gt;&lt;br /&gt;文件放在：&lt;br /&gt;/Developer/Documentation/RubyCocoa&lt;br /&gt;&lt;br /&gt;範例放在：（相當豐富）&lt;br /&gt;/Developer/Examples/RubyCocoa&lt;br /&gt;&lt;br /&gt;我這裡有一個簡化的 hello world, 可以小瞥一下：&lt;br /&gt;&lt;br /&gt;require 'osx/cocoa'&lt;br /&gt;include OSX&lt;br /&gt;&lt;br /&gt;app = NSApplication.sharedApplication&lt;br /&gt;&lt;br /&gt;hello = NSWindow.alloc.initWithContentRect_styleMask_backing_defer [200.0, 300.0, 100.0, 100.0], 15, 2, 0&lt;br /&gt;hello.setTitle 'Hello'&lt;br /&gt;&lt;br /&gt;btn = NSButton.alloc.initWithFrame [10.0, 10.0, 80.0, 80.0]&lt;br /&gt;hello.contentView.addSubview btn&lt;br /&gt;btn.setTitle 'Hello World!'&lt;br /&gt;btn.setAction 'stop:'&lt;br /&gt;btn.setBezelStyle 4&lt;br /&gt;&lt;br /&gt;hello.display&lt;br /&gt;hello.orderFrontRegardless&lt;br /&gt;&lt;br /&gt;app.run&lt;br /&gt;&lt;br /&gt;另外可以順便請教一下，如何讓視窗在按下 X 時關閉而不是隱藏嗎？我沒寫過 obj-c（XD）, 昨天文件翻來翻去找不到要怎麼做&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;另一方面，如果只是要做 GUI 而不需要 call mac 的 api 的話，個人強力推薦 QtRuby&lt;br /&gt;&lt;br /&gt;sudo port install qt4-mac（這個會 build 很久）&lt;br /&gt;sudo port install cmake&lt;br /&gt;&lt;br /&gt;QtRuby 沒有這麼方便的安裝法，要到&lt;br /&gt;http://rubyforge.org/projects/korundum/&lt;br /&gt;抓 qt4-qtruby, 然後進到目錄下：&lt;br /&gt;&lt;br /&gt;cmake .&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;br /&gt;&lt;br /&gt;於是就可以正常使用 QtRuby 了，hello world 如下：&lt;br /&gt;&lt;br /&gt;require 'qt'&lt;br /&gt;include Qt&lt;br /&gt;app = Application.new ARGV&lt;br /&gt;hello = PushButton.new "Hello World!"&lt;br /&gt;hello.resize 100, 30&lt;br /&gt;hello.show&lt;br /&gt;app.exec&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Qt 是什麼？&lt;br /&gt;http://trolltech.com/products/qt&lt;br /&gt;是我用過最棒的 GUI toolkit, 使用 C++ 語言。可用 GPL 授權或用商業授權（很貴），二擇一（這是 Qt 唯一被批評的點）&lt;br /&gt;&lt;br /&gt;Ruby 是什麼？&lt;br /&gt;http://ruby-lang.org/&lt;br /&gt;是我用過最方便的 programming language, 使用 Ruby license（很自由）歡迎來 ptt Ruby 板參觀 :p&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Mac OS 10.5 將搭載 Ruby 1.8.6 + Rails 1.2.3, 想試試 Rails 寫網站嗎？&lt;br /&gt;sudo gem install rails&lt;br /&gt;不需要等 10.5 就可以輕鬆試驗了 XD&lt;br /&gt;http://rubyonrails.org/&lt;br /&gt;&lt;br /&gt;==&lt;br /&gt;&lt;br /&gt;發完神經了，有傷眼請見諒 XD&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;&lt;pre&gt;#!/usr/bin/ruby          [露比] /Programming (Kn|N)ight/            看板《Ruby》&lt;br /&gt;# if a dog nailed extra legs that          http://www.ptt.cc/bbs/Ruby/index.html&lt;br /&gt;# walks like an octopus, and                            Welcome ~Ruby@ptt~&lt;br /&gt;# talks like an octopus, then       ◢█◣            http://www.ruby-lang.org/&lt;br /&gt;# we are happy to treat it as       █                http://www.ruby-doc.org/&lt;br /&gt;# if it were an octopus.            ◥  ◤            http://www.rubyforge.org/&lt;/pre&gt;--&lt;br /&gt;※ 發信站: 批踢踢實業坊(ptt.cc)&lt;br /&gt;◆ From: 220.135.28.18&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-959331202414590505?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/959331202414590505/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=959331202414590505' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/959331202414590505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/959331202414590505'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/07/rubycocoa.html' title='[心得] RubyCocoa'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-7203864790369875406</id><published>2007-07-22T14:23:00.000+08:00</published><updated>2007-07-23T19:29:38.139+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gui'/><title type='text'>Ruby GUI</title><content type='html'>[begin edited2]&lt;br /&gt;夠了，不要再修改了，後續請看 telnet://ptt.cc 的 Ruby 板或是：&lt;br /&gt;http://godfat.tw/viewtopic.php?p=1779#1779&lt;br /&gt;（我電腦關機或沒使用網路時連不上）&lt;br /&gt;[end edited2]&lt;br /&gt;&lt;br /&gt;[begin edited]&lt;br /&gt;&lt;br /&gt; 作者  godfat (godfat 真常)                                        看板  Ruby &lt;br /&gt; 標題  Re: [心得] GUI                                                         &lt;br /&gt; 時間  Sun Jul 22 18:13:32 2007                                               &lt;br /&gt;───────────────────────────────────────&lt;br /&gt;&lt;br /&gt;說是這樣說，不過真正開始測試的時候，我發覺﹍&lt;br /&gt;&lt;br /&gt;1. wxRuby&lt;br /&gt;實在有點難用﹍有一堆不該有的參數要傳來傳去﹍放棄&lt;br /&gt;&lt;br /&gt;2. FXRuby&lt;br /&gt;mac 上其實是可以用啦﹍只是需要 X11, 不能用 Aqua&lt;br /&gt;結果就是﹍對 user 來說很難用，放棄&lt;br /&gt;&lt;br /&gt;3. QtRuby&lt;br /&gt;結果還是得回到 QtRuby...&lt;br /&gt;cmake .&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;br /&gt;&lt;br /&gt;測試了一下，正常可用 Qt4&lt;br /&gt;不過市面上的文件好像以 Qt3 為多就是了&lt;br /&gt;&lt;br /&gt;嘖，沒有 port install qtruby 真的很可惜&lt;br /&gt;這樣以後要升級或是反安裝就比較麻煩了&lt;br /&gt;不知道當初安裝的 source 是不是要留下來以便反安裝作業&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;--&lt;br /&gt;※ 發信站: 批踢踢實業坊(ptt.cc) &lt;br /&gt;&lt;br /&gt;[end edited]&lt;br /&gt;&lt;br /&gt;關於 computer science 這個領域，除了程式語言（programming language）與物件導向（object-oriented）外，再下一個興趣大概就是使用者圖形介面了吧（GUI）. 所以我一直想找個自己喜歡的 toolkit 來用，在 C++ 中無非就是 Qt4 了，不過在 Ruby 中，似乎沒有一個比較完美的 solution, 一個個來看。&lt;br /&gt;&lt;br /&gt;在這之前，我先說明一下我用過的 C/C++/Java GUI toolkit.&lt;br /&gt;&lt;br /&gt;1. MFC, 學校在教如何剪貼 MFC code, 我是叛逆份子，所以一個字都沒聽進去。不用別人說很糟，光看第一眼就覺得很糟，更何況他又是被罵得半死的東西。&lt;br /&gt;&lt;br /&gt;2. wxWidgets, 這算是我第一個使用的 GUI toolkit, 基本上，我認為這真的是個很強大的東西，沒話說。不過最令人嘖嘖稱奇的應該是他跨平台的能力，如果我沒記錯的話，他跨的平台好像比 Java 還多！不過因為風格問題，我不是很喜歡。基本上，我認為 wxWidgets 的風格有些過於老舊，寫起來感覺不是很好。Ruby binding 叫 wxRuby.&lt;br /&gt;&lt;br /&gt;3. Qt, 我想正是因為 wxWidgets 跟我不太合，所以才繼續找下去。不料找到 Qt4, 我認為這應該是接近完美的 solution 了。有人說，Qt 至少領先其他人十年，也許這麼講並不為過。最令人詬病的，大概就是你只能從 GPL 或超昂貴的商業 solution 兩種 license 中選一種。其實我不覺得這對我來說會是很大的困擾，open source 沒什麼不好，雖然 GPL 是有點太激進了些。Ruby binding 叫 QtRuby.&lt;br /&gt;&lt;br /&gt;4. GTK+, 這個其實我不只沒用過，甚至連看都沒看過。理由很簡單，就是我不想用 C 想用 C++. 當然我知道 GTK+ 評價不錯，也有 Glade 和 win32 的 port, 只是似乎沒有足夠的推力讓我去嘗嘗看。&lt;br /&gt;&lt;br /&gt;5. Swing, 會碰這個完全只是因為需要用 Java. 我個人是覺得他跟 wxWidgets 各有千秋，但同樣遠遜於 Qt. 不過也許這樣比較並不太公平，Java 天生就是沒 C++ 強。所以 Qt 遠勝可能是理所當然的？Ruby 要用可以使用 JRuby.&lt;br /&gt;&lt;br /&gt;6. Ultimate++, 其實這個我沒用過，不過看起來是不錯。沒去試主要有三個原因，一，他綁 IDE, 這個我很不爽。二，他的命名法我不能接受。三，Qt 很好。XD 其實你去看他的網站，他有一個範例程式，並用各種 toolkit 來實做。我個人認為這個動作滿不誠懇的，他有故意挑其他人弱點的嫌疑。而且各 toolkit 做到的東西明顯有差異，這樣比並不公平。不誠懇，不喜歡。&lt;br /&gt;&lt;br /&gt;7. Notus/VCF, 這兩樣 toolkit 都有一個很大的特色，就是 template template and template... 基本上用 C++ 當然是要用 template 啊！！不過知道這兩樣東西時我已經有一段時間沒碰 GUI 了，所以並沒有仔細調查這兩個 toolkit 感覺如何。但我想如果沒辦法接受 Qt 的話，這兩套 toolkit 值得一看。&lt;br /&gt;&lt;br /&gt;8. .NET/mono, 這個其實我只用過 Visual C++ 2005 Express 稍微拉了一下介面，感覺還不錯，但直接寫起程式不知道是什麼感覺。Ruby 要用的話，或許可以試試 IronRuby, 不過我個人對 .NET 沒什麼好感，就不去試了。&lt;br /&gt;&lt;br /&gt;9. VCL, Borland 的招牌，我用過 Turbo C++ Explorer, 感覺是﹍基本上我覺得沒有 .NET 好的感覺。而且要跨平台恐怕有點難，所以就不考慮了。更何況這些好像也不算 open source 的吧？&lt;br /&gt;&lt;br /&gt;10. FOX, 這個是我最沒聽過的 toolkit, 是去找 Ruby GUI 時才發現他的存在，所以我一點都不知道他的狀況究竟如何。評價似乎是不錯，而且好像很年輕。只是呢﹍FXRuby 似乎沒有 mac 的 port, 而我也已經有點懶得用 C++ 寫 GUI 了，所以還是暫時跳過吧﹍。基本上沒有跨 win32/x11/aqua 三大系統的 toolkit, 我就沒什麼興趣試了。&lt;br /&gt;&lt;br /&gt;本來只想隨意講一點的，不知不覺就扯多了。接下來看 Ruby 能使用的東西：&lt;br /&gt;&lt;br /&gt;1. tk, 沒記錯的話，這個被 ruby 內建起來了。不過似乎是用過的都說爛，所以還是不要多考慮吧？&lt;br /&gt;&lt;br /&gt;2. FXRuby, FOX 的 ruby binding, 評價相當不錯，唯一的缺點也許是還沒有 mac 版的樣子？我想未來應該值得繼續關切，雖然我還沒看過他程式寫起來像什麼樣子。要試用的話，除了需要安裝 FOX, FXRuby 就：gem install fxruby&lt;br /&gt;&lt;br /&gt;3. wxRuby, wxWidgets 的 ruby binding, 我是看到有人批評寫起來像在寫 C++, 這應該算是一個滿大的缺點，不過看在他功能強大，跨平台能力驚人的份上，還是值得試試看吧。要試用的話，除了需要安裝 wxWidgets, wxRuby 就：gem install wxruby&lt;br /&gt;&lt;br /&gt;4. QtRuby, Qt3 與 Qt4 的 ruby binding, 基本上評價仍然是相當地好，唯一的兩大缺點，第一個是沒有 gem, 不能 gem install qtruby, 第二個是在 windows 上要安裝似乎非常困難，沒有簡單的方法。但我相信假以時日，這兩個問題都能夠解決（嗚嗚）。&lt;br /&gt;&lt;br /&gt;5. Swing, 要灌 JRuby, 我的 macports 似乎找不到 jruby, 我又不想從 sun 的網站抓下來灌，再說，我也沒喜歡過 swing 過，所以就懶得試了。&lt;br /&gt;&lt;br /&gt;6. Mono, 我有灌 mono, 不過不是很清楚能不能用 IronRuby 之類的東西存取，之所以寫在這，算是做個筆記，說不定可以使用這樣。&lt;br /&gt;&lt;br /&gt;7. GTK+, 我不是很確定有沒有 ruby binding, 但我想應該會有才是。不試的理由同上，所以也只是暫時筆記。&lt;br /&gt;&lt;br /&gt;Ruby 的 GUI 比較有名的大概就這幾個了吧。其實我是一直想試 QtRuby 的，雖然 windows 上似乎不太容易使用，但相信假以時日一定可以的。而讓我卻步最大的問題點在於，不能用 gem 安裝，macports 也找不到 QtRuby. 也就是說，我得親自 ./configure make make install, 但我不喜歡這樣，管理不便。所以我決定還是暫時放下他，等他有 gem 或是 port 時再說吧！&lt;br /&gt;&lt;br /&gt;FXRuby 因為沒用過 FOX, 所以也還是放著再說。更何況據說是沒有 mac 版，那我試屁啊﹍。所以左右思量之下，我還是決定先試 wxRuby! 安裝方便，強大的跨平台能力，雖然是 C++ style 而非 the ruby way, 但對我來說 C++ style 也不是那麼地令人排斥，也許有點詭異，但我覺得也可以用自己想要的方式重新 wrap 一次，對 ruby 來說那是如此簡單的事！&lt;br /&gt;&lt;br /&gt;so have a try with wxRuby!&lt;br /&gt;&lt;br /&gt;this is the hello world:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;require 'rubygems'&lt;br /&gt;require 'wx'&lt;br /&gt;&lt;br /&gt;class HelloWorld &lt; Wx::App&lt;br /&gt;  include Wx&lt;br /&gt;  def on_init&lt;br /&gt;    helloframe = Frame.new nil, -1, "Hello World"&lt;br /&gt;    StaticText.new helloframe, -1, "Hello World"&lt;br /&gt;    helloframe.show&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;HelloWorld.new.main_loop&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;sudo port install wxwidgets&lt;br /&gt;sudo gem install wxruby&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7203864790369875406?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/7203864790369875406/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=7203864790369875406' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7203864790369875406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7203864790369875406'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/07/ruby-gui.html' title='Ruby GUI'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-1384774345217489579</id><published>2007-07-22T11:16:00.000+08:00</published><updated>2007-07-22T11:22:29.777+08:00</updated><title type='text'>閉關百日</title><content type='html'>即日起，本人即將到關西營區閉關百日，休養生息以及盡男生該盡的義務，大概今年十一月回來。新兵訓練出來後，就是國防役的生活啦。&lt;br /&gt;&lt;br /&gt;對了，因為新訓好像可以看點書，所以預計會帶本練功秘笈進去練功&lt;br /&gt;HTTP：The Definitive Guide&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_8vS0KjIsbko/RqLLewHCCdI/AAAAAAAAAIw/GNUcUCTXeII/s1600-h/1565925092_cat.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_8vS0KjIsbko/RqLLewHCCdI/AAAAAAAAAIw/GNUcUCTXeII/s320/1565925092_cat.gif" alt="" id="BLOGGER_PHOTO_ID_5089854258052991442" border="0" /&gt;&lt;/a&gt;前陣子太忙了，都沒時間看書練鍊基本功好像也不錯。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1384774345217489579?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/1384774345217489579/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=1384774345217489579' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1384774345217489579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1384774345217489579'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/07/blog-post.html' title='閉關百日'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_8vS0KjIsbko/RqLLewHCCdI/AAAAAAAAAIw/GNUcUCTXeII/s72-c/1565925092_cat.gif' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-6153779235710577517</id><published>2007-07-11T13:36:00.000+08:00</published><updated>2007-07-11T18:57:54.158+08:00</updated><title type='text'>Passion</title><content type='html'>昨天我的一個好朋友告訴我「我好像失去了程式設計的熱情了。」我聽著這句話，突然覺得我蠻幸福。&lt;br /&gt;&lt;br /&gt;要說我從來沒有這種感嘆是騙人的。上上次擁有這種想法的時候，我那時正被論文跟 PHP 搞的很疲憊，剛好遇到 Ruby on Rails ，那種超乎想像的設計讓我完全掉入這個世界，也重新找回程式真正的熱情。&lt;br /&gt;&lt;br /&gt;上次出現這樣的想法的時候，剛好是前陣子案子太忙，事情多到我想殺人。一連串的忙碌讓我忘記了寫程式帶給我的快樂，只是一直感覺到累累累。Ruby on Rails 的東西也是這樣，成長的很快，但是我是不是跟著他一起成長呢？還是一直原地踏步呢？我到底追求的是什麼呢？我得到了什麼呢？&lt;br /&gt;&lt;br /&gt;很幸運，這種疲憊感很快的就不見了，因為我接了這個 Case ，&lt;a href="http://jonescup.roodo.com/"&gt;29屆瓊斯盃網站&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://jonescup.roodo.com/images/agents/A3/header.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://jonescup.roodo.com/images/agents/A3/header.gif" alt="" border="0" /&gt;&lt;/a&gt;小時候，我看著東方，阿龍，阿三等人在瓊斯盃奮鬥，現在呢？我以官網製作者的身份，坐在場邊看著中華隊在場上奮鬥。不一樣的我，一樣為中華隊加油的心情。我為了這個案子，連續熬夜好幾個晚上，連 Blog  都沒時間寫了，就是為了呈現一個最好的瓊斯盃網站。這麼堅持的理由不是因為專業，只是因為我是一個運動迷，我是一個中華隊的球迷，我要為他們加油。&lt;br /&gt;&lt;br /&gt;累是超級累，但是我找回了失去的「Passion」。一個專門屬於我的 Passion。不瞞各位，我 7/23 就要進去軍中新訓三個月，在進去軍中之前可以做出一個這們有意義的東西，真的很開心。&lt;br /&gt;&lt;br /&gt;一年前我開了這個 Blog ，也是這樣的熱情不是嗎？&lt;br /&gt;&lt;br /&gt;我以身為 Ruby on Rails 使用者自豪，我以身為第29屆瓊斯盃官網製作者自豪。不管你是誰，用什麼語言，什麼 Framework，別忘記你的熱情，千萬要對你的工作感到自豪。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6153779235710577517?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/6153779235710577517/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=6153779235710577517' title='5 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6153779235710577517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6153779235710577517'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/07/passion.html' title='Passion'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-1391892624570737619</id><published>2007-07-08T22:19:00.000+08:00</published><updated>2007-07-08T22:22:28.859+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='gem'/><title type='text'>ruby facets</title><content type='html'>老實講，ruby 有一個地方真討厭，那就是每次都把我想做的東西做完了。有了 ruby, 我不覺得還有需要再自己弄一個程式語言，做得比我想像中的還好。唯一的缺點大概只有 lib 還不夠多，但有了 facets 的話，那也真的是差不多了。&lt;br /&gt;&lt;a href="http://facets.rubyforge.org/"&gt;http://facets.rubyforge.org/&lt;/a&gt;&lt;br /&gt;該有的幾乎都有了，差的只剩下一些小東西。如果早點發現這東西，大概就不會想弄 ludy 了吧。&lt;br /&gt;&lt;br /&gt;不過想用 facets 有點麻煩，例如我想用 Array#shuffle, 就必須&lt;br /&gt;require 'rubygems'&lt;br /&gt;require 'facets'&lt;br /&gt;require 'array/shuffle'&lt;br /&gt;這麻煩到爆炸了吧！！不過有個好東西：&lt;br /&gt;&lt;br /&gt;require 'rubygems'&lt;br /&gt;require 'facets/automatic'&lt;br /&gt;&lt;br /&gt;接下來，就放心使用 Array#shuffle 吧！因為 automatic 會自動幫你 require... 我沒去看他的實做，但我猜是建 table 吧。有一個小缺點，例如你想這樣做：&lt;br /&gt;&lt;br /&gt;[1,2,3].shuffle.map &amp;:to_s&lt;br /&gt;&lt;br /&gt;很不幸，這樣會失敗。shuffle 可以正常自動 require, 但是 Symbol#to_proc 不能藉由這個方法自動 require. 如果你寫：&lt;br /&gt;&lt;br /&gt;[1,2,3].shuffle.map &amp;:to_s.to_proc&lt;br /&gt;&lt;br /&gt;這樣是 ok 的，automatic 可以自動 require 該 require 的東西。問題大概出在，&amp;:to_s 是 implicit call, automatic 偵測不到。所以第一次使用，還是必須明確說明需要用到 Symbol#to_proc, 接下來就可以快樂地使用&lt;br /&gt;&lt;br /&gt;[1,2,3].shuffle.map &amp;:to_s&lt;br /&gt;&lt;br /&gt;了。或是前面自己手動 require:&lt;br /&gt;&lt;br /&gt;require 'rubygems'&lt;br /&gt;require 'facets'&lt;br /&gt;require 'facets/automatic'&lt;br /&gt;&lt;br /&gt;第二行的 require 可以讓你使用 Symbol#to_proc, 所以就可以直接寫：&lt;br /&gt;&lt;br /&gt;[1,2,3].shuffle.map &amp;:to_s&lt;br /&gt;&lt;br /&gt;快去安裝 facets 吧！！&lt;br /&gt;gem install facets&lt;br /&gt;另一個 ruby web framework nitro 0.41.0 也有用到 facets !! 雖然是用 1.4.5 版的，而現在最新的 facets 是 1.8.54（以 2007.07.08 為準的最新版本）有機會也可以試試 nitro&lt;br /&gt;gem install nitro&lt;br /&gt;官方網站是：&lt;br /&gt;&lt;a href="http://www.nitroproject.org/"&gt;http://www.nitroproject.org/&lt;/a&gt;&lt;br /&gt;缺點非常明確！幾乎沒有文件 XD 我很少看到一個東西的文件可以少到這樣。&lt;br /&gt;&lt;br /&gt;不多說了，我現在頭痛就算了，眼睛也很痛。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1391892624570737619?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/1391892624570737619/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=1391892624570737619' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1391892624570737619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1391892624570737619'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/07/ruby-facets.html' title='ruby facets'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-6010030514660445761</id><published>2007-06-25T08:57:00.000+08:00</published><updated>2007-06-25T20:52:50.956+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='push'/><title type='text'>淺談 Comet PUSH Server 架構</title><content type='html'>最近有機會碰到 Comet 或是 PUSH Server 這類的技術，剛好一直覺得之前寫的 &lt;a href="http://lightyror.thegiive.net/2006/11/comet-for-ruby-on-rails-and-mongrel.html"&gt;Comet For Ruby on Rails and Mongrel&lt;/a&gt;不夠有感覺，所以再寫一次。這裡先得講一聲，我的認知就是 Comet == Server PUSH ，有錯請告知。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;HTTP 統治網路界&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;簡單來說，一般的 Socket Programming 都是保持一個雙向的連線，可以送可以收。但是 HTTP Design 為了以下理由，設計方向為單向的。&lt;ol&gt;&lt;li&gt;提高 Server 處理效能&lt;/li&gt;&lt;li&gt;方便作 cache，Proxy 容易融入&lt;br /&gt;&lt;/li&gt;&lt;li&gt;方便作 Server Farm&lt;/li&gt;&lt;li&gt;網路發展初期，實體硬體狀況不佳，很容易造成 connection lose，單向傳輸可以有效避免瞬斷&lt;/li&gt;&lt;/ol&gt;我跟你 request ，你回我 HTML ，交易完成，connection close，This is HTTP。&lt;br /&gt;&lt;br /&gt;如果以 HTTP 當初設計的初衷「&lt;span style="font-weight: bold;"&gt;文件交換&lt;/span&gt;」來看，我們發現到他設計的非常的好，也相當成功的在當初糟糕的網路環境下成功的生存下來。但是就是因為 HTTP 設計太成功了，導致現在網路業者一股腦兒將各式各樣的 App 放在 HTTP 的架構上，想要用當初只是為了文件交換的協定，變成一個包山包海的協定，自然產生很多問題。&lt;br /&gt;&lt;br /&gt;HTTP 最大的問題在於&lt;span style="font-weight: bold;"&gt;即時性&lt;/span&gt;。&lt;br /&gt;&lt;br /&gt;要解決 HTTP 的即時性的問題，有 Polling 跟  Server PUSH 這兩種方式。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Polling&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;我們想要做到即時傳訊，Server 端觸發 Client 事件等等功能，以現行的 HTTP 架構下，都得利用 Polling 的方式來做到。Polling 其實也就是現在的 RSS Reader 的作法，RSS Reader 會每過半個小時，或是一個小時去問對方 Server 有沒有新文章。用 Polling來作即時性的功能，最大的好處在於容易寫，因為他完全符合 HTTP 的架構，但是最大的壞處在於不夠即時。以 RSS Reader 來說，每過一個小時去問有沒有新文章，代表的意思就是有一整個小時的空窗期，你得每過一個小時才知道有沒有新文章。&lt;br /&gt;&lt;br /&gt;以 RSS Reader 的屬性來說，採用 Polling 有很多好處&lt;br /&gt;&lt;ol&gt;&lt;li&gt;我其實不需要知道立刻知道有多少新文章，使用者對於 RSS 的即時性需求沒那麼高&lt;/li&gt;&lt;li&gt;Blog 系統多變，與其設定一個各 Blog 系統共通的 Socket 協定，不如設定一個共通的文件交換格式來的簡單&lt;/li&gt;&lt;/ol&gt;但是如果使用聊天室，即時訊息傳遞，Polling 就不是一個好主意了。聊天最怕不夠即時，所以必須加快 Polling Interval，但是會帶來「提高 Server 負載」的後果。你一分鐘 Polling 一次，跟一小時一次，前者的負載是後者的 60 倍。等於你用負載換來即時性。這個在人一多的情況下會造成相當大的負擔。&lt;br /&gt;&lt;br /&gt;因為 Polling 在某些地方不是那麼的好，所以才有 Server PUSH 機制出現。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Server PUSH&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Server PUSH 是建構在建立一個不中斷的 Socket Connection 下面。一個作法是使用 iframe ，送出的header中要把content-type設為” multipart/x-mixed-replace”，來保持一個不間斷的 HTTP Connection。另外一個作法就是用 Flash 來跟 Server 建立一個 xmlsocket。保持一個不中斷的 Connection ，代表 Server 有新訊息就可以直接傳給 Client，不用等待 Client 過來 request。&lt;br /&gt;&lt;br /&gt;這樣可以帶來的好處就是，Server 有狀態更新才會有網路傳輸，如果沒有狀態更新，就不會浪費資源。而 Polling 是不管有沒有狀態更新，都得花上固定的網路傳輸成本，當然就會比較浪費資源。&lt;br /&gt;&lt;br /&gt;舉個例子，考試成績快出來了，你每個小時都從宿舍去公佈欄看成績出來了沒，假設成績沒那麼快出來，你自然會花上許多無意義的時間在宿舍到公佈欄之間的往返上面（ Polling ）。但是如果老師有你的手機（不斷線的 Connection ），成績公佈老師就打電話給你，告訴你的成績（Server Push）。這樣不是好多了嗎？&lt;br /&gt;&lt;br /&gt;但是你會問，假設老師打電話給你，你在收不到訊號的地方怎麼辦？假設班上人數太多，老師不是就會打電話打到手軟？&lt;br /&gt;&lt;br /&gt;這剛好講到 Server PUSH 的壞處，第一個壞處是假設 Client 網路不好，connection 造成瞬斷，那麼你的訊息就會消失不見了。另外一個壞處就是，持續性的 connection 很難做到 Load Sharing機制，通常大家都只會跟同一台  PUSH Server 作連接，這台 PUSH Server 在人一多就會產生大負載度的問題。這當然有辦法解決，只是這就已經要討論到很深的地方了。&lt;br /&gt;&lt;br /&gt;雖然 Server PUSH 不是萬能的。不過整體來說，以傳遞「&lt;span style="font-weight: bold;"&gt;即時性需求高的訊息來說&lt;/span&gt;」，PUSH Server 帶來的好處絕對會比 Polling 來的好，這倒是無庸置疑的。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6010030514660445761?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/6010030514660445761/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=6010030514660445761' title='9 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6010030514660445761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6010030514660445761'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/comet-push-server.html' title='淺談 Comet PUSH Server 架構'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-3722670899844448890</id><published>2007-06-23T16:50:00.000+08:00</published><updated>2007-06-23T16:53:57.679+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='active_resource'/><title type='text'>Active Resource 已經打包成 GEM 了</title><content type='html'>Rails 1.2 的最新力作 Active Resource 已經是 beta 的 gem 了，以後安裝的人就不用每次都用 svn 下載了。&lt;br /&gt;&lt;br /&gt;安裝方式就是 &lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;gem install activeresource —source http://gems.rubyonrails.org&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-3722670899844448890?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/3722670899844448890/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=3722670899844448890' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3722670899844448890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3722670899844448890'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/active-resource-gem.html' title='Active Resource 已經打包成 GEM 了'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-3940551874842028080</id><published>2007-06-22T08:42:00.000+08:00</published><updated>2007-06-22T15:49:29.653+08:00</updated><title type='text'>SliceHost 入手</title><content type='html'>我是程式設計師，工作以外的日子，我希望能夠有一台 Server 讓我搞一些小玩意，那我該怎麼辦。&lt;br /&gt;&lt;br /&gt;通常大家會推薦 Share Web Hosting。但是仔細想想我們對 Share Web Hosting 第一個印象是什麼？大家一起用一台 Apache，一起用一台 MySQL，好擠呀。想用啥新服務不行，要等公司覺得有商業立基再說，好煩呀。想開個其他 PORT 來跑東西，不行。想幹嘛...不行，不行，不行。敝公司覺得你想要搞垮我們，所以你不可以。充其量，這些 Share Web Hosting 公司只是為了一般不了解架站的大眾而服務。但是像我們這種可以獨立控制一台 Linux 的人，就是不爽。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div dragover="true"&gt;那 Dedicated Server 呢？我們看看 &lt;a href="http://www.godaddy.com/gdshop/hosting/build.asp?isc=gooh2002aa&amp;display=dedicated"&gt;Godaddy 的價碼&lt;/a&gt;，最經濟方案 63.00美金一個月。嗯嗯恩....我爸不是李嘉誠，我們也不是要搞公司，也只好重重拿起廣告單，輕輕的放下。&lt;br /&gt;&lt;br /&gt;我們發現到市面上只有兩個選擇。很便宜的 Web Hosting 跟很貴的 Dedicated Server。可是中間有一個&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;想要一台&lt;/span&gt;&lt;span style="font-style: italic;"&gt;便宜又方便的&lt;/span&gt;&lt;span style="font-style: italic;"&gt; Server 玩玩&lt;/span&gt;&lt;/blockquote&gt;的斷層。我們已經厭倦了 Web Hosting 的不自由，但是又沒有 Dedicated Server的需求。以前這樣的需求只能夠自己架站。但是架站的網路，電源，機房等等問題又讓我們卻步。我們是 RD ，我們想玩 Server ，但是不想碰硬體的東西。&lt;br /&gt;&lt;br /&gt;這時候 &lt;a href="http://www.slicehost.com/"&gt; slicehost&lt;/a&gt;  這樣的 &lt;a href="http://en.wikipedia.org/wiki/Vps"&gt;Virtual Private Server&lt;/a&gt; 服務就是我們的解藥，當你付錢給 slicehost 後，他會給你一台 Linux 機器讓你玩，你可以 ssh 進去，你有 Root 權限，你有獨立 IP，你擁有一整台機器可以玩，而且價錢是剛好坐落在 Web Hosting 跟 Dedicated Server 中間，等於你每個月花20~30美金的價碼請一個專職網管幫你管機器，什麼硬碟壞掉，CPU 燒掉，主機板進水等等事情都不用煩惱，你只需要寫你的程式即可。&lt;br /&gt;&lt;br /&gt;至於他還有很多優點&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;第一個&lt;/span&gt;是 SliceHost 有 5種 Linux 可以自由選擇，Ubuntu，Gentoo，CentOS，Debian，Fedora，你可以自由的選擇你想要的 OS。而且這裡有一個小插曲，我一開始選錯了 OS ，本來想說要寄信給 SliceHost 公司請他們換 OS，沒想到他們提供了 rebuild slice 的功能，你可以線上就把你的 Server OS 換掉。而且這個功能等於是當你被破台的時候，還是可以重灌 OS。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;第二個&lt;/span&gt;是因為他是 Ruby on Rails 寫的後台。並且網頁提供一個 &lt;a href="http://antony.lesuisse.org/qweb/trac/wiki/AjaxTerm"&gt;AJAX Term&lt;/a&gt; console mode，當你機器 reboot 的時候，你可以看到你的 Linux 正在重開的畫面，或是當你重灌 Linux 的時候，你可以看到目前重灌的進度，有你在機房修機器的 fu~~~（註1）&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;第三個&lt;/span&gt;是 SliceHost 標榜不超賣，大家說 Performance 很不錯。&lt;br /&gt;&lt;br /&gt;價錢我是選擇 20美金一個月的方案，256MB Ram + 10G Storage + 100G Bandwith 很夠用了。而網路上面&lt;a href="http://blog.tinyau.net/archives/2007/06/13/first-experience-with-virtual-private-server/"&gt;大家&lt;/a&gt;&lt;a href="http://blog.pbg4.org/2007/6/12/rails-on-slicehost-1"&gt;提到&lt;/a&gt;一個很重要的問題，大家說因為 SliceHost 太熱門了，申請要等快一個月的情況並沒有發生，我只等半天。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;註1&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;這個 console mode 真的好有fu~~&lt;br /&gt;重灌畫面&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_8vS0KjIsbko/Rns2lbvdpcI/AAAAAAAAAIk/bplbdu4AwGw/s1600-h/%E6%93%B7%E5%9C%96_4.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/_8vS0KjIsbko/Rns2lbvdpcI/AAAAAAAAAIk/bplbdu4AwGw/s320/%E6%93%B7%E5%9C%96_4.png" alt="" id="BLOGGER_PHOTO_ID_5078713021520258498" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;登入 console&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_8vS0KjIsbko/RnsqiLvdpZI/AAAAAAAAAIM/eRYMpbXUJ8c/s1600-h/%E6%93%B7%E5%9C%96_1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_8vS0KjIsbko/RnsqiLvdpZI/AAAAAAAAAIM/eRYMpbXUJ8c/s320/%E6%93%B7%E5%9C%96_1.png" alt="" id="BLOGGER_PHOTO_ID_5078699771546150290" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;開機畫面&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_8vS0KjIsbko/RnsrFrvdpbI/AAAAAAAAAIc/7A2NnOTpszQ/s1600-h/%E6%93%B7%E5%9C%96_3.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_8vS0KjIsbko/RnsrFrvdpbI/AAAAAAAAAIc/7A2NnOTpszQ/s320/%E6%93%B7%E5%9C%96_3.png" alt="" id="BLOGGER_PHOTO_ID_5078700381431506354" border="0" /&gt;&lt;/a&gt;Reboot 畫面&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_8vS0KjIsbko/Rnsq8bvdpaI/AAAAAAAAAIU/52GtTt9rXgk/s1600-h/%E6%93%B7%E5%9C%96_2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/_8vS0KjIsbko/Rnsq8bvdpaI/AAAAAAAAAIU/52GtTt9rXgk/s320/%E6%93%B7%E5%9C%96_2.png" alt="" id="BLOGGER_PHOTO_ID_5078700222517716386" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-3940551874842028080?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/3940551874842028080/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=3940551874842028080' title='8 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3940551874842028080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3940551874842028080'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/slicehost.html' title='SliceHost 入手'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_8vS0KjIsbko/Rns2lbvdpcI/AAAAAAAAAIk/bplbdu4AwGw/s72-c/%E6%93%B7%E5%9C%96_4.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-6285527901550372582</id><published>2007-06-20T19:21:00.000+08:00</published><updated>2007-06-21T00:17:07.091+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='說明'/><title type='text'>300篇達成，版面大修</title><content type='html'>這位客官，你沒走錯，為了慶祝本 Blog 邁向第三百篇文章，我在版面上作了很大幅度的改變。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1. 搜尋改用 Google&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;我發現到 Blogger Nav Bar 的搜尋真是爛到極點，所以我砍了 Blogger Nav Bar，並且在側邊欄直接呼叫外掛 Google 大神來幫我作搜尋，大家以後可以直接使用右邊的 Search Bar 來搜尋本站的文章。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2. 版型大改&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;版型改成我最喜歡的白底黑字，而特別的字就用紅色。除此之外我拿掉幾乎所有的 Blog 的小玩意，包含繼續閱讀，Tag Cloud...等等最 Javascript。這個動作的原因是因為我發現&lt;br /&gt;&lt;blockquote&gt;來看我的 Blog 的人，你們只是來看內容而已&lt;/blockquote&gt;這個趨勢從 Google Analysis 就可以知道&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_8vS0KjIsbko/RnkTJbvdpYI/AAAAAAAAAIE/lnOpE8HZ0Cc/s1600-h/%E6%93%B7%E5%9C%96_2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_8vS0KjIsbko/RnkTJbvdpYI/AAAAAAAAAIE/lnOpE8HZ0Cc/s320/%E6%93%B7%E5%9C%96_2.png" alt="" id="BLOGGER_PHOTO_ID_5078111107623527810" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;這是我某段時間流量的來源的統計圖，我們可以發現到超過一半以上的人是被 Google 大神抓進來，然後查到你想要的東西，走人。&lt;br /&gt;&lt;br /&gt;這個推論，也從本 Blog 黏度只有 2.09 個可以知道（註1），我的觀眾都是查詢資料，查完一兩個網頁之後走人，也不會逗留。&lt;br /&gt;&lt;br /&gt;就一般網頁的角度來說，我該做出一些事情來增加黏性呢，但是想想不對&lt;br /&gt;&lt;blockquote&gt;等等，幹嘛增加黏性呢？這是一件好事呀。&lt;/blockquote&gt;因為我當初成立 本 Blog 的目標，就是一個知識為主的 Blog 。而上述現象代表我的 Blog 越來越 Wiki 化了，使用者看待這個 Blog 是一個已知識為主的網頁，而非一個閒聊的網頁。與其弄一堆拉哩佈達的東西讓大家傷眼睛，還不如砍掉所有無意義的部份，只留下最簡單的黑底白字 ，讓大家查詢的時候更加的快而迅速的查到相關的資料。這才是友善的對待顧客吧 。&lt;br /&gt;&lt;br /&gt;所以我改了版面，希望大家喜歡。&lt;br /&gt;&lt;br /&gt;註1&lt;br /&gt;黏度：點閱網頁/造訪數&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6285527901550372582?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/6285527901550372582/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=6285527901550372582' title='9 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6285527901550372582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6285527901550372582'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/300.html' title='300篇達成，版面大修'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_8vS0KjIsbko/RnkTJbvdpYI/AAAAAAAAAIE/lnOpE8HZ0Cc/s72-c/%E6%93%B7%E5%9C%96_2.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-8602877535632117197</id><published>2007-06-18T00:26:00.000+08:00</published><updated>2007-06-19T12:47:36.332+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>Textile，RedCloth，Vim</title><content type='html'>&lt;div id="revision"&gt;        &lt;p&gt;&lt;strong&gt;Textile&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;有在用 Instiki 的人就知道，他是使用 &lt;a href="http://en.wikipedia.org/wiki/Textile_%28markup_language%29"&gt;Textile&lt;/a&gt;  這種語法。當 Web 大流行之後，大家發現到 Web 當中的核心 &lt;span class="caps"&gt;HTML &lt;/span&gt;語法，雖然設計的很有彈性，但是 HTML 實在不是為了方便人書寫而設計的，裡面格式相當的囉唆而且難以書寫閱讀。為了書寫方便，所以產生 Textile 這種 &lt;a href="http://en.wikipedia.org/wiki/Lightweight_markup_language"&gt;Light Weight Markup Language&lt;/a&gt; 語法。&lt;/p&gt;    &lt;p&gt;Textile 的使用方式就不再詳加介紹了，可以看看 &lt;a href="http://en.wikipedia.org/wiki/Textile_%28markup_language%29"&gt;Wikipedia的介紹&lt;/a&gt; ，總之 Ruby on Rails 上面很多套件都相當友善的支援 Textile。&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;span class="newWikiWord"&gt;Red Cloth&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;剛剛說到 Ruby and Ruby on Rails 上面很多套件都支援 Textile，他們都是靠 &lt;a href="http://whytheluckystiff.net/ruby/redcloth/"&gt;RedCloth&lt;br /&gt;&lt;/a&gt; 這個 Gem 來支援的。他是一個相當容易使用的 Ruby Plugin，安裝方式就是&lt;/p&gt;    &lt;blockquote&gt;   &lt;p&gt;gem i redcloth&lt;/p&gt;  &lt;/blockquote&gt;    &lt;p&gt;而使用方式就是&lt;/p&gt;    &lt;blockquote&gt;   &lt;p&gt;require ‘redcloth’&lt;br /&gt;html = ”&lt;strong&gt;strong text&lt;/strong&gt; and &lt;em&gt;emphasized text&lt;/em&gt;”&lt;br /&gt;r = &lt;span class="newWikiWord"&gt;RedCloth&lt;/span&gt;.new(html)&lt;br /&gt;r.to_html&lt;/p&gt;  &lt;/blockquote&gt;    &lt;p&gt;如何，很容易看的懂吧。&lt;/p&gt;    &lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;vim&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;剛剛看到網路上面強者這篇 &lt;a href="http://blog.aaronbieber.com/2007/05/30/editing-textile-in-vim/"&gt;Editing Textile in &lt;span class="caps"&gt;VIM&lt;/span&gt;&lt;/a&gt; ，裡面介紹如何使用 Vim 來編輯 Textile，並且提供 &lt;a href="http://blog.aaronbieber.com/blog/articles/TextileInVIM/textile.vim"&gt;Textile Syntax File&lt;/a&gt; [1]。要使用他首先得先把這個 text.vim 放到&lt;span style="font-size:100%;"&gt; &lt;strong&gt;&lt;sub&gt;/.vim/syntax/&lt;/sub&gt;&lt;/strong&gt;&lt;sub&gt; 底下，再來&gt;將 &lt;strong&gt;&lt;/strong&gt;&lt;/sub&gt;&lt;strong&gt;/.vim/filetype.vim&lt;/strong&gt; 加入一行&lt;/span&gt;&lt;/p&gt;    &lt;blockquote&gt;   &lt;p&gt;au BufNewFile,BufRead *.textile setf textile&lt;/p&gt;  &lt;/blockquote&gt;    &lt;p&gt;假設使用 vim 編輯副檔名為 textile 的檔案，例如 xxx.textile，你就會發現他已經 S#ntax Highlight 過了。&lt;/p&gt;&lt;p id="fn1"&gt;&lt;sup&gt;註1&lt;/sup&gt; &lt;a href="http://arbor.ee.ntu.edu.tw/%7Ewisely/download/textile.vim"&gt;我的 Mirror&lt;/a&gt;&lt;/p&gt;    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8602877535632117197?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/8602877535632117197/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=8602877535632117197' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8602877535632117197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8602877535632117197'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/textileredclothvim.html' title='Textile，RedCloth，Vim'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-8037469057932615229</id><published>2007-06-17T08:46:00.001+08:00</published><updated>2007-06-17T17:22:57.862+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby activerecord_jdbc'/><title type='text'>用 JRuby 來連接 Oracle</title><content type='html'>JRuby 為 Ruby on Rails 帶來的效果已經出現了。&lt;br /&gt;&lt;br /&gt;根據 &lt;a href="http://rawblock.blogspot.com/2007/06/ruby-oracle-mac-os-x-pain-jruby-and.html" style=""&gt;這篇文章 ，裡面提到了Oracle在 &lt;/a&gt;&lt;span class="caps"&gt;MAC OS X 上面支援度相當的差勁。沒有 standard client 也沒有 standard Oracle C libraries，導致 &lt;/span&gt;&lt;span class="caps"&gt;MAC OS X 上面，用 Ruby 連結到 Oracle 是一個&lt;/span&gt;&lt;strong&gt;Painful Job。&lt;/strong&gt;以前遇到這檔事情，大家只能摸摸鼻子，說聲「再加強」。但是現在有了萬能超人 JRuby ，我們交給 &lt;span class="caps"&gt;JDBC 來解決這檔事情。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;首先，按照 我說的方式&lt;a hrf="http://lightyror.thegiive.net/2007/06/jruby.html"&gt;安裝 JRuby &lt;/a&gt;還有 &lt;a href="http://lightyror.thegiive.net/2007/06/jruby-on-rails.html" style=""&gt;ActiveRecord JDBC&lt;/a&gt;。我文章裡面裡面提到的是如何安裝 MySQL ，要改連接到 Oracle 也是同樣的方式。去 &lt;a href="http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html" style="text-decoration: none;"&gt;Oracle’s &lt;span class="caps" style="text-decoration: underline;"&gt;JDBC download page &lt;/span&gt;&lt;/a&gt;&lt;br /&gt;下載 ojdbc14.jar ，放到 $JRuby_HOME/lib/ 下面或是 export&lt;span class="caps"&gt;CLASSPATH=ojdbc14.jar。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;然後在 Config 這樣設定即可&lt;br /&gt;&lt;pre style="text-align: left;"&gt;production:&lt;/pre&gt;&lt;pre style="text-align: left;"&gt;&lt;span class="symbol" style=""&gt;adapter: &lt;/span&gt;&lt;span class="punct" style=""&gt;&lt;span style="font-weight: bold;"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="string" style="background-image: initial; background-repeat: initial; background-attachment: initial; background-position-x: initial; background-position-y: initial; background-color: rgb(255, 255, 238); "&gt;jdbc&lt;/span&gt;&lt;span class="punct" style=""&gt;&lt;span style="font-weight: bold;"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="text-align: left;text-align: left; "&gt;&lt;span class="punct" style=""&gt;&lt;span class="symbol" style=""&gt;driver: &lt;/span&gt;&lt;span class="punct" style=""&gt;&lt;span style="font-weight: bold;"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="string" style="background-image: initial; background-repeat: initial; background-attachment: initial; background-position-x: initial; background-position-y: initial; background-color: rgb(255, 255, 238); "&gt;oracle.jdbc.driver.OracleDriver&lt;/span&gt;&lt;span class="punct" style=""&gt;&lt;span style="font-weight: bold;"&gt;'&lt;span class="punct" style=""&gt;&lt;span class="symbol" style=""&gt;&lt;span style="font-weight: normal;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="text-align: left;text-align: left; "&gt;&lt;span class="punct" style=""&gt;&lt;span class="punct" style=""&gt;&lt;span style="font-weight: bold;"&gt;&lt;span class="punct" style=""&gt;&lt;span class="symbol" style=""&gt;&lt;span style="font-weight: normal;"&gt;url: &lt;/span&gt;&lt;/span&gt;&lt;span class="punct" style=""&gt;'&lt;/span&gt;&lt;span class="string" style="background-image: initial; background-repeat: initial; background-attachment: initial; background-position-x: initial; background-position-y: initial; background-color: rgb(255, 255, 238); "&gt;&lt;span style="font-weight: normal;"&gt;jdbc:oracle:thin:@server:1521:database&lt;/span&gt;&lt;/span&gt;&lt;span class="punct" style=""&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="text-align: left;text-align: left; "&gt;&lt;span class="punct" style=""&gt;&lt;span class="symbol" style=""&gt;username: &lt;/span&gt;&lt;span class="punct" style=""&gt;&lt;span style="font-weight: bold;"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="string" style="background-image: initial; background-repeat: initial; background-attachment: initial; background-position-x: initial; background-position-y: initial; background-color: rgb(255, 255, 238); "&gt;username&lt;/span&gt;&lt;span class="punct" style=""&gt;&lt;span style="font-weight: bold;"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="text-align: left;text-align: left; "&gt;&lt;span class="punct" style=""&gt;&lt;span class="symbol" style=""&gt;password: &lt;/span&gt;&lt;span class="punct" style=""&gt;&lt;span style="font-weight: bold;"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="string" style="background-image: initial; background-repeat: initial; background-attachment: initial; background-position-x: initial; background-position-y: initial; background-color: rgb(255, 255, 238); "&gt;password&lt;/span&gt;&lt;span class="punct" style=""&gt;&lt;span style="font-weight: bold;"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;哈哈哈，Oracle 可以忽略 &lt;span class="caps"&gt;MAC 上面的用戶，可以忽略 Ruby 的用戶，但是他不能忽略 &lt;/span&gt;&lt;span class="caps"&gt;JAVA 上面的用戶呀，有了 JRuby 真是太美好了。&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8037469057932615229?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/8037469057932615229/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=8037469057932615229' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8037469057932615229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8037469057932615229'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/jruby-ruby-on-rails-oracle-mac-os-x.html' title='用 JRuby 來連接 Oracle'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-573358628855970019</id><published>2007-06-15T21:08:00.000+08:00</published><updated>2007-06-16T11:39:52.795+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><title type='text'>JRuby 的未來</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_8vS0KjIsbko/RnNaXLvdpXI/AAAAAAAAAH8/Nx_yYblxMf8/s1600-h/duke-ruby.gif"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 127px; height: 147px;" src="http://bp2.blogger.com/_8vS0KjIsbko/RnNaXLvdpXI/AAAAAAAAAH8/Nx_yYblxMf8/s320/duke-ruby.gif" alt="" id="BLOGGER_PHOTO_ID_5076500559312037234" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;右邊這張圖是從 JRuby 老大Charles Nutter 的&lt;a href="http://headius.blogspot.com/2007/05/jruby-t-shirt.html"&gt; Blog 裡面 Copy 過來的&lt;/a&gt;（註1）。象徵的意涵是 Java Programmer 面對目前 Java 當前的問題，拼了老命尋找解法，卻發現他們找到了 Ruby 這個發光的寶石。&lt;br /&gt;&lt;br /&gt;言歸正傳，JRuby 當初發展到 1.0 的目標就是 &lt;span style="font-weight: bold;"&gt;Ruby compatibility&lt;/span&gt;，而且似乎也已經達成了。而 JRuby 未來的路要怎麼走呢？&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;JRuby 的主要開發者 Charles Nutter 也早就&lt;a href="http://headius.blogspot.com/2007/06/jruby-100rc3-released-and-this-is-it.html"&gt;明示&lt;/a&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;繼續加強速度&lt;/li&gt;&lt;li&gt;Java Integration加強，1.1 可能會重寫整個 Lib&lt;br /&gt;&lt;/li&gt;&lt;li&gt;支援 Ruby 2.0 還有 Rubinius 產生的 Bytecode&lt;/li&gt;&lt;/ol&gt;無獨有偶，Ola Bini 在接受&lt;a href="http://www.infoq.com/news/2007/04/great-expectations-jruby"&gt; InfoQ 訪問時&lt;/a&gt;也提到未來 JRuby 走向&lt;br /&gt;&lt;ol&gt;&lt;li&gt;效能加強&lt;/li&gt;&lt;li&gt;正確性加強&lt;/li&gt;&lt;li&gt;Java Integration加強&lt;/li&gt;&lt;li&gt;Java ByteCode Compiler&lt;/li&gt;&lt;/ol&gt;也就是說，&lt;span style="font-weight: bold;"&gt;效能&lt;/span&gt;，&lt;span style="font-weight: bold;"&gt;正確性&lt;/span&gt;，跟 &lt;span style="font-weight: bold;"&gt;Java 整合度&lt;/span&gt;，以及 &lt;span style="font-weight: bold;"&gt;ByteCode Compiler&lt;/span&gt; 是未來 JRuby 努力的目標。&lt;br /&gt;&lt;br /&gt;關於 JRuby 未來的 core team 部分，繼 &lt;a href="http://lightyror.thegiive.net/2006/09/sun-jruby.html"&gt;JRuby 兩個作者接受了 SUN 的 offer&lt;/a&gt; ，全職工作 JRuby 之後的九個月，Ola Bini 也接受了 &lt;a href="http://ola-bini.blogspot.com/2007/03/thoughtworks.html"&gt;ThoughtWorks &lt;/a&gt;的全職工作，性質也是付錢給他開發 JRuby core。JRuby 已經完全顛覆了以往 Open Source 開發者做公益的宿命，三個主要開發者都有人付錢請他們開發。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ola-bini.blogspot.com/2007/04/jruby-099-released.html"&gt;Ola Bini 上個月提到&lt;/a&gt;，JRuby又加入了兩個新的 core team member，Marcin Mielżyński 和 Bill Dortch。顯然 JRuby 社群是相當活躍的， 而且商業力量也一直進駐，他的開發速度怎麼看都覺得會繼續狂飆。&lt;br /&gt;&lt;br /&gt;JRuby 這東西前途不可限量。&lt;br /&gt;&lt;br /&gt;註 1&lt;br /&gt;我找不到圖片的 License，只好著名出處，有版權問題請告知。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-573358628855970019?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/573358628855970019/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=573358628855970019' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/573358628855970019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/573358628855970019'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/jruby_15.html' title='JRuby 的未來'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_8vS0KjIsbko/RnNaXLvdpXI/AAAAAAAAAH8/Nx_yYblxMf8/s72-c/duke-ruby.gif' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-7716866314076926674</id><published>2007-06-13T21:39:00.000+08:00</published><updated>2007-06-13T21:52:05.181+08:00</updated><title type='text'>Leopard 立志成為最好的 Ruby on Rails 開發平台</title><content type='html'>蘋果自從發現到 Ruby on Rails 使用者有一大部分都是使用 MAC 之後，開始在 OS 上面狂推猛推用力推 Ruby on Rails。到底蘋果支援到什麼程度呢？看看&lt;a href="http://www.apple.com/macosx/leopard/technology/unix.html"&gt;這一頁吧&lt;/a&gt;，未來的 OSX 10.5 Leopard 會直接 Boundle 進去 Ruby 1.8.6，Rails ，Mongrel，Capistrano 。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Scripting Bridge.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    &lt;p&gt;Mac OS X is now the ideal platform for all kinds of script-based development. Ruby 1.8.6 and Python 2.5 are both first-class languages for Mac development, thanks to Cocoa bridges, Xcode and Interface Builder support, DTrace monitoring, and Framework builds — plus AppleEvent bindings via the new Scripting Bridge. Leopard is also the premier platform for &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; development, thanks to Rails, &lt;a href="http://mongrel.rubyforge.org/"&gt;Mongrel&lt;/a&gt;, and &lt;a href="http://www.capify.org/"&gt;Capistrano&lt;/a&gt; bundling. &lt;/p&gt;聽起來真的很美好，蘋果擁有偉大的 TextMate Editor，跟完全 Native Bundling 的 Ruby on Rails 全套 Package，再加上漂亮的介面，讓我一定會乖乖的掏出錢來買 Leopard。唯一的問題就是，Leopard 到底何時出呢？&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7716866314076926674?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/7716866314076926674/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=7716866314076926674' title='6 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7716866314076926674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7716866314076926674'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/leopard-ruby-on-rails.html' title='Leopard 立志成為最好的 Ruby on Rails 開發平台'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-1374028080886047003</id><published>2007-06-10T16:16:00.000+08:00</published><updated>2007-06-12T17:38:19.791+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>vim 上面使用 ruby 的方式</title><content type='html'>最近聽到有人在問 vim 上面怎麼使用 ruby，尤其是怎麼縮排的問題，我在這邊稍微提一下怎麼用。其實 vim 的設計就是使用 configuration 來做到支援不同語言，但是撰寫 vim 設定檔其實不是一件很簡單的事情，所以才有 vim-ruby 的存在。&lt;a href="http://vim-ruby.rubyforge.org/"&gt;vim-ruby &lt;/a&gt;是一個 gem package，只要使用他就可以幫你簡單的做好 vim 上面對 ruby 的支援。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;安裝 vim-ruby &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;gem i vim-ruby&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;安裝 vim-ruby configuration file&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;vim-ruby 有附一支 ruby script ，叫做 vim-ruby-install.rb，在安裝 vim-ruby gems 之後，你的路徑下面就會出現這隻 script ，請打入&lt;br /&gt;&lt;blockquote&gt;vim-ruby-install.rb&lt;br /&gt;&lt;/blockquote&gt;幫助你自動的把相關的 Syntax ，indent config 檔案放到相關的目錄下。以下就是他會出現的選項&lt;br /&gt;&lt;blockquote&gt;Possible Vim installation directories:&lt;br /&gt;  1) /home/wisely/.vim&lt;br /&gt;  2) /usr/share/vim/vimfiles&lt;br /&gt;&lt;/blockquote&gt;第一個是在講說，將相關 vim-ruby config 安裝在自己目錄下面，只有自己可以使用。第二個就是放在系統的 vim config 下面，不過你當時的權限要 root 才能安裝。原則上兩個都可以啦。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;不能縮排的解法&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;本來這樣的步驟，在我 notebook 上面這樣就可以完全無誤的使用了。但是當我最近新裝另外一台機器的時候，我發現裝好 vim-ruby 之後，很奇怪的 vim 有 syntax highlight，但是卻沒有程式碼縮排。&lt;br /&gt;&lt;br /&gt;後來我發現到，只要將我 notebook 上面的 .vimrc 放到新裝的機器上面即可做到縮排，所以&lt;br /&gt;&lt;blockquote&gt;問題不在於 vim-ruby，而是沒有適當的 .vimrc &lt;/blockquote&gt;雖然用 vim 很久了，但是依舊沒有很深入的去了解怎麼去設定，真是很慚愧。不管怎麼說，我先將我的 &lt;a href="http://phpfi.com/240645"&gt;.vimrc &lt;/a&gt;放上網路，大家確認一下是否可以使用。這隻 .vimrc 陪我征戰大江南北，目前為止還不錯用。&lt;br /&gt;&lt;br /&gt;UPDATE:&lt;br /&gt;&lt;br /&gt;根據網友提醒，&lt;a href="http://wiki.rubyonrails.org/rails/pages/HowtoUseVimWithRails"&gt;Ruby on Rails Wiki 網頁&lt;/a&gt;有講到只要在 .vimrc 裡面加入&lt;br /&gt;&lt;blockquote&gt; set nocompatible          " We're running Vim, not Vi!&lt;br /&gt; syntax on                 " Enable syntax highlighting&lt;br /&gt; filetype plugin indent on " Enable filetype-specific indenting and plugins&lt;br /&gt;&lt;br /&gt; " Load matchit (% to bounce from do to end, etc.)&lt;br /&gt; runtime! macros/matchit.vim&lt;br /&gt;&lt;br /&gt; augroup myfiletypes&lt;br /&gt;   " Clear old autocmds in group&lt;br /&gt;   autocmd!&lt;br /&gt;   " autoindent with two spaces, always expand tabs&lt;br /&gt;   autocmd FileType ruby,eruby,yaml set ai sw=2 sts=2 et&lt;br /&gt; augroup END&lt;/blockquote&gt;這些即可。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1374028080886047003?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/1374028080886047003/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=1374028080886047003' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1374028080886047003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1374028080886047003'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/vim-ruby.html' title='vim 上面使用 ruby 的方式'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-7935347468356356684</id><published>2007-06-08T17:29:00.000+08:00</published><updated>2007-06-08T18:25:57.344+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>JRuby on Rails 安裝方式</title><content type='html'>有了號稱可以跑 Rails 的 JRuby ，當然要來試試看 JRuby on Rails 怎麼安裝。因為我的 test 機器上面已經有裝好原先的 Ruby 跟 Rails ，所以我們就每個指令都打全部的執行檔路徑避免搞混。本 Tutorial 在 Linux 上面測試成功。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;安裝 Rails&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;JRuby 有附帶一個 gems 在 $JRuby_PATH/bin/ 底下。我們使用我們最熟悉的方式來裝，就是 gem 安裝&lt;br /&gt;&lt;blockquote&gt;$JRuby_PATH/bin/gem i rails -y&lt;br /&gt;&lt;/blockquote&gt;他會安裝 Rails package 到   $JRuby_PATH/lib/ruby/gems/1.8/gems/ 底下。以後所有的 JRuby Gems 都會安裝到這個下面。安裝好了後，$JRuby_PATH/bin/  會多出 rails 這個指令，這個就是我們熟悉的 rails command。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;安裝 MySQL JDBC Driver&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;因為 JRuby 不能裝我們熟悉的 ruby-mysql，所以使用 JDBC 來操作 MySQL。你可以到任何地方去安裝 MySQL JDBC Driver 的 jar 檔案，但是如果不知道那裡抓的話，可以試試看 MySQL 官方的 &lt;a href="http://dev.mysql.com/downloads/connector/j/5.0.html"&gt;Connector/J&lt;/a&gt; 。然後  mysql-connector-java.jar 檔案放到 $JRuby_HOME/lib/ 底下。(註1）&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;安裝 ActiveRecord-JDBC&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;這是 Active Record 跟 JDBC 的介面，用 gem 來安裝&lt;br /&gt;&lt;blockquote&gt;$JRuby_PATH/bin/gem i  ActiveRecord-JDBC&lt;/blockquote&gt;安裝好了之後就可以使用 JDBC 來 Connection MySQL。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;新增 Rails APP&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;熟悉的指令來了，只是請確定你是使用 JRuby 的 rails 來新增 Rails App&lt;br /&gt;&lt;blockquote&gt;$JRuby_HOME/bin/rails app_name&lt;/blockquote&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;修改 Enviroment config &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;rails 的 config/enviroment.rb 要稍微修改&lt;br /&gt;&lt;blockquote&gt;Rails::Initializer.run do |config|&lt;br /&gt;end&lt;/blockquote&gt;裡面要加上&lt;br /&gt;&lt;blockquote&gt;  RAILS_CONNECTION_ADAPTERS = 'jdbc'&lt;br /&gt;&lt;/blockquote&gt;這句，不然會出現 error。（註2）&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Database config 修改&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;因為改成 JDBC 了，所以 config/database.yml 也會改成&lt;br /&gt;&lt;blockquote&gt;development:&lt;br /&gt;__adapter: jdbc&lt;br /&gt;__driver: com.mysql.jdbc.Driver&lt;br /&gt;__url: jdbc:mysql://localhost:3306/資料庫名稱&lt;br /&gt;__username: root&lt;br /&gt;__password:&lt;/blockquote&gt;這個樣子的設定方式，原先的 database 選項是無效的，必須放在 url 選項的最後面才可以使用。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;啟動 Rails Server&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;終於要啟動了，啟動方式就是&lt;br /&gt;&lt;blockquote&gt; jruby script/server &lt;/blockquote&gt;他會啟動 webrick 。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;註1&lt;/span&gt;&lt;br /&gt;我試過 $CLASSPATH 的方式，但是無法還是無法正確 connection ，會出現以下 error&lt;br /&gt;&lt;blockquote&gt;The driver encountered an error: cannot load Java class com.mysql.jdbc.Driver&lt;/blockquote&gt;所以我採用這個方式。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;註2 &lt;/span&gt;&lt;br /&gt;當沒有寫入  config/enviroment.rb ，啟動時會出現下列 error&lt;br /&gt;&lt;blockquote&gt;&gt;  jruby script/server&lt;br /&gt;=&gt; Booting WEBrick...&lt;br /&gt;/home/wisely/jruby-1.0/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract/connection_specification.rb:209:in `establish_connection': database configuration specifies nonexistent jdbc adapter (ActiveRecord::AdapterNotFound)&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7935347468356356684?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/7935347468356356684/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=7935347468356356684' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7935347468356356684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7935347468356356684'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/jruby-on-rails.html' title='JRuby on Rails 安裝方式'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-194139640312275598</id><published>2007-06-08T11:10:00.000+08:00</published><updated>2007-06-08T14:32:57.154+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><title type='text'>JRuby 安裝方式</title><content type='html'>JRuby 1.0 出了，我們開始看看怎麼安裝吧，這裡先測試 Linux 上面安裝方式。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;前置動作&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;你的系統必須安裝好&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Java 1.4 以上&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ant&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;下載  JRuby Source&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;你可以到&lt;a href="http://dist.codehaus.org/jruby/"&gt;官方下載區&lt;/a&gt;，或是&lt;a href="http://arbor.ee.ntu.edu.tw/%7Ewisely/download/jruby/jruby-src-1.0.tar.gz"&gt;我的 Mirror &lt;/a&gt;下載 Source Package。將他解壓縮。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Compile JRuby&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;他有 bin 的版本的，不過我還是喜歡 compile 。只要有系統有 ant，我們直接打&lt;br /&gt;&lt;blockquote&gt;&gt; ant&lt;br /&gt;&lt;/blockquote&gt;即可 compile。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;執行檔路徑指定&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;jruby 的執行檔在 ./bin/jruby 下面，請將 PATH 路徑指到這裡。並且確定你的 JAVA_HOME 變數沒錯。&lt;br /&gt;&lt;blockquote&gt;&gt; PATH=$PATH:/你的/jruby/根目錄/bin&lt;br /&gt;&gt; JAVA_HOME=/你的/java/根目錄&lt;br /&gt;&lt;/blockquote&gt;這樣以後執行 jruby gem 才沒有問題。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;測試看看&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;指定好目錄後，直接打&lt;br /&gt;&lt;blockquote&gt;&gt;  jruby -v&lt;br /&gt;ruby 1.8.5 (2007-06-08 rev 3841) [i386-jruby1.0]&lt;/blockquote&gt;看看有沒有問題。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;執行第一支 JRuby 程式&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;寫一支簡單的 Ruby 程式，這裡採用之前&lt;a href="http://lightyror.thegiive.net/2007/05/jruby.html"&gt; JRuby 代表的意義&lt;/a&gt;範例 code。&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;require&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'java'&lt;/span&gt;&lt;br /&gt;include_class &lt;span style="color: rgb(0, 128, 0);"&gt;'java.util.Random'&lt;/span&gt;&lt;br /&gt;r &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; Random.new&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;123&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;puts&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"Some random number &lt;span style="color: rgb(32, 64, 160);"&gt;#{r.nextInt % 10}&lt;/span&gt;"&lt;/span&gt;&lt;br /&gt;r.seed &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;456&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;puts&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"Another random number &lt;span style="color: rgb(32, 64, 160);"&gt;#{r.nextInt % 10}&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;然後來測試&lt;br /&gt;&lt;blockquote&gt;&gt; jruby random.rb&lt;br /&gt;Some random number 9&lt;br /&gt;Another random number 0&lt;br /&gt;&lt;/blockquote&gt;呵呵，成功了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-194139640312275598?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/194139640312275598/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=194139640312275598' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/194139640312275598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/194139640312275598'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/jruby.html' title='JRuby 安裝方式'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-1342468015597070971</id><published>2007-06-08T09:18:00.000+08:00</published><updated>2007-06-08T10:51:21.902+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><title type='text'>JRuby 1.0 Release</title><content type='html'>雖然&lt;a href="http://jruby.codehaus.org/"&gt;官網&lt;/a&gt;還沒有講，不過&lt;a href="http://dist.codehaus.org/jruby/"&gt; Download 區&lt;/a&gt;已經有了1.0版了。將將將，Ruby 有始以來最受期待的 VM&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;blockquote&gt;JRuby 1.0 Release 啦～～～～～～～&lt;/blockquote&gt;&lt;/span&gt;&lt;/span&gt;我這裡為台灣地區 Mirror 一下檔案，這是&lt;a href="http://arbor.ee.ntu.edu.tw/%7Ewisely/download/jruby/jruby-src-1.0.tar.gz"&gt; src 檔案&lt;/a&gt;，這是&lt;a href="http://arbor.ee.ntu.edu.tw/%7Ewisely/download/jruby/jruby-bin-1.0.tar.gz"&gt; bin  檔案&lt;/a&gt;。接下來的幾天，每天都要開始介紹 JRuby 的題目歐。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1342468015597070971?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/1342468015597070971/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=1342468015597070971' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1342468015597070971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1342468015597070971'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/jruby-10-release.html' title='JRuby 1.0 Release'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-7124878062782199526</id><published>2007-06-04T17:08:00.000+08:00</published><updated>2007-06-04T22:58:10.341+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='安裝'/><title type='text'>在 CentOS 安裝 Ruby on Rails</title><content type='html'>昨天在 CentOS 安裝 Ruby on Rails 的時候，我發現到雖然用 &lt;a href="http://lightyror.thegiive.net/2007/05/rubyworks-001-release.html"&gt;RubyWorks&lt;/a&gt; 來安裝很快，但是有些小細節還是得注意。所以還是寫一個 Tutorial 好了。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;1. 安裝 RubyWorks &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;安裝 RubyWorks Repo&lt;br /&gt;&lt;blockquote&gt;wget http://rubyworks.rubyforge.org/public_key.txt&lt;br /&gt;sudo rpm --import public_key.txt&lt;br /&gt;wget http://rubyworks.rubyforge.org/RubyWorks.repo&lt;br /&gt;cp RubyWorks.repo /etc/yum.repos.d/&lt;br /&gt;&lt;/blockquote&gt;用 yum 安裝 RubyWorks&lt;br /&gt;&lt;blockquote&gt;yum install rubyworks&lt;br /&gt;&lt;/blockquote&gt;安裝好 RubyWorks ，他會把 ruby，rubygems，Mongrel，Haproxy，Monit 安裝跟設定好。但是他不會安裝 Rails ，而是 copy 一份 Rails 在 /usr/rails 上面，這其實是很正確的作法，因為他一開始就取向 Production Server，而 Production Server 本來就該將 Rails 版本 Freeze 在 Rails Doc 裡面。但是如果還是要在 CentOS 安裝 Rails Gem，那就&lt;br /&gt;&lt;blockquote&gt;gem i rails -y &lt;/blockquote&gt;即可。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;2. 安裝 MySQL &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;RubyWorks 好歸好，就是沒有選擇讓我們裝 DB Server，我們這裡就直接用 yum 安裝 MySQL&lt;br /&gt;&lt;blockquote&gt;yum install mysql-server &lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;3. 安裝 Ruby MySQL Native Lib&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;我發現到 RubyWorks 並不會安裝 Ruby MySQL Native Lib，所以我們得用 gem 安裝，但是又發現 centos 上面安裝 MySQL Gem 會出現這樣的錯誤訊息，網路上也&lt;a href="http://smangal.wordpress.com/2007/05/17/mysql-gem-on-centos/"&gt;有人在 complian&lt;/a&gt;。&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;checking for mysql_query() in -lmysqlclient… no&lt;br /&gt;checking for main() in -lm… yes&lt;br /&gt;checking for mysql_query() in -lmysqlclient… no&lt;br /&gt;checking for main() in -lz… yes&lt;br /&gt;checking for mysql_query() in -lmysqlclient… no&lt;br /&gt;checking for main() in -lsocket… no&lt;br /&gt;checking for mysql_query() in -lmysqlclient… no&lt;br /&gt;checking for main() in -lnsl… yes&lt;br /&gt;checking for mysql_query() in -lmysqlclient… no&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;*** extconf.rb failed ***&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Could not create Makefile due to some reason, probably lack of&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;necessary libraries and/or headers. Check the mkmf.log file for more&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;details. You may need configuration options.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Provided configuration options:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;–with-opt-dir&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;所以得先 remove MySQL 然後再重新安裝 MySQL 跟 MySQL Development Lib&lt;br /&gt;&lt;blockquote&gt;yum remove mysql&lt;br /&gt;yum install mysql&lt;br /&gt;yum install mysql-devel&lt;br /&gt;gem install mysql&lt;br /&gt;&lt;/blockquote&gt;至於為何這樣，我也不太清楚。反正 work 就好啦。&lt;br /&gt;&lt;br /&gt;這樣應該就安裝完成了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7124878062782199526?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/7124878062782199526/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=7124878062782199526' title='6 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7124878062782199526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7124878062782199526'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/centos-ruby-on-rails.html' title='在 CentOS 安裝 Ruby on Rails'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-767526653306358565</id><published>2007-06-04T14:56:00.000+08:00</published><updated>2007-06-04T17:03:34.696+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><title type='text'>JRuby ，Ruby 界的救世主？</title><content type='html'>今天早上看到 ericsk’s blog 的 &lt;a href="http://blog.ericsk.org/archives/644"&gt;JRuby 1.0 開始倒數&lt;/a&gt;，就回去看 Charles Nutter 的原文&lt;a href="http://headius.blogspot.com/2007/06/jruby-100rc3-released-and-this-is-it.html"&gt; JRuby 1.0.0RC3 Released - And This Is It!&lt;/a&gt;，我發現到 JRuby 很多東西真的很值得一提。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;1. JRuby 1.0 這周上市&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;6/3 JRuby 1.0 RC3 發佈，1.0 Release 也將在這周發表，他將是 Ruby 1.8.5 compatible 的。&lt;br /&gt;&lt;blockquote&gt;The only things that will change from now until a 1.0 final release later this week would be any showstopping bugs that are extremely low-impact to fix. In general, RC3 should be nearly identical to 1.0 final.&lt;/blockquote&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;2. 效率不錯，並且會引進 JIT&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;JRuby 1.0 會有 JIT Compiler ，代表可以 compile ruby code，並且大多數的時候可以跑得比一般 Ruby 1.8 快。 Rails 用 JRuby 跑在 Java Application Server 上面的效果一般來說很不賴。但是因為 JRuby 1.0 之前主打的是跟 Java 的整合度，所以可以作的事情還有很多。&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;We've had anecdotal reports that JRuby on Rails in a Java application server performance extremely well, and other reports that general Ruby applications perform somewhat poorly. The general performance situation is not well-understood, but we all agree there's a lot more work to be done. &lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;3.  跟 Java 整合不錯，但是可以再加強&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;大部份的時間 call lib 跟 繼承 class 都沒太多問題，不過有些 case 還是沒搞定。這個問題將會在 JRuby 1.1 的時候，以重新 Design Lib 的方式來解決。&lt;br /&gt;&lt;br /&gt;基本上其他的東西就不提了，光是 JRuby 1.0 可以跑 Rails 跟可以 JIT Compile 就值得大書特書了。如果實做的沒有太大的問題的話，說不定是下一個 Ruby 跟  Rails 的高峰。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-767526653306358565?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/767526653306358565/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=767526653306358565' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/767526653306358565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/767526653306358565'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/jruby-ruby.html' title='JRuby ，Ruby 界的救世主？'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-2861264537853925517</id><published>2007-06-03T10:10:00.000+08:00</published><updated>2007-06-03T16:03:29.095+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Rails 2.0 預計的新特色</title><content type='html'>Ruby on Rails 作者 DHH 在 &lt;a href="http://conferences.oreillynet.com/rails/"&gt;Rails Conf 2007&lt;/a&gt; 主題演講 A peak at Rails 2.0，裡面提到很多 Rails 2.0 預計有的新功能，大致上還是走「加強 REST ，修改許多細節，尤其是 performance 」的方向走，現在我們就來 check 一下吧。由於投影片沒有講得很清楚，我也順便看了 Robbin 的 &lt;a href="http://robbin.javaeye.com/blog/85647"&gt;railsconf2007大会介绍&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;更好的 REST 支援&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ActiveResource 正式 release ，不再只能去 check svn 來 download&lt;/li&gt;&lt;li&gt;有了更輕巧的 REST ， Action Web Service 要移出 Rails Core&lt;/li&gt;&lt;li&gt;HTTP Basic Auth 支援，解決 REST 對於 Auth 的問題&lt;br /&gt;&lt;/li&gt;&lt;li&gt;respond_to 可以直接輸出 RJS&lt;br /&gt;&lt;/li&gt;&lt;li&gt;更強大的 mine_type&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;更好的 performance &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;最大的消息就是有 query cache 可以用了。並且他加了不少 static file 處理的強化技巧。可以用&lt;br /&gt;&lt;pre&gt;&lt;span style="color:#4444ff;"&gt;&lt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;%= javascript_include_tag :all , :cache =&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt; &lt;strong&gt;true&lt;/strong&gt; %&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#4444ff;"&gt;&lt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;%= stylesheet_include_tag :all , :cache =&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt; &lt;strong&gt;true&lt;/strong&gt; %&lt;span style="color:#4444ff;"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;自動合併以及壓縮一些 css 或是 js static file，順便下 cache。&lt;br /&gt;&lt;br /&gt;而且可以在 config 裡面設置&lt;br /&gt;&lt;pre&gt;config.action_controller.asset_host &lt;span style="color:#4444ff;"&gt;=&lt;/span&gt; &lt;span style="color:#008000;"&gt;'static%d.example.com'&lt;/span&gt;&lt;/pre&gt;讓 images ，js，css 的 render 出來的路徑變成&lt;br /&gt;&lt;pre&gt;&lt;span style="color:#2040a0;"&gt;&lt;strong&gt;&lt;span style="color:#4444ff;"&gt;&lt;strong&gt;&lt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="color:#2040a0;"&gt;img&lt;/span&gt; &lt;span style="color:#2040a0;"&gt;src=&lt;/span&gt;&lt;span style="color:#008000;"&gt;"static1.example.com"&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;&lt;strong&gt;&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="color:#2040a0;"&gt;&lt;strong&gt;&lt;span style="color:#4444ff;"&gt;&lt;strong&gt;&lt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="color:#2040a0;"&gt;img&lt;/span&gt; &lt;span style="color:#2040a0;"&gt;src=&lt;/span&gt;&lt;span style="color:#008000;"&gt;"static2.example.com"&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;&lt;strong&gt;&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;類似這樣的形式，可以簡單的將 static file 分離到 static server。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;更簡單的 Migration &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;你很討厭寫 t.column  嗎？現在，你可以這樣寫&lt;br /&gt;&lt;pre&gt;create_table &lt;span style="color:#4444ff;"&gt;:&lt;/span&gt;people &lt;strong&gt;do&lt;/strong&gt; |t| &lt;br /&gt; t.first_name &lt;span style="color:#4444ff;"&gt;:&lt;/span&gt;type&lt;span style="color:#4444ff;"&gt;=&gt;:&lt;/span&gt;string &lt;br /&gt; &lt;span style="color:#4444ff;"&gt;...&lt;/span&gt; &lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/pre&gt;以及&lt;br /&gt;&lt;pre&gt;create_table &lt;span style="color:#4444ff;"&gt;:&lt;/span&gt;people &lt;strong&gt;do&lt;/strong&gt; |t| &lt;br /&gt; t.string &lt;span style="color:#4444ff;"&gt;:&lt;/span&gt;first_name &lt;br /&gt; &lt;span style="color:#4444ff;"&gt;...&lt;/span&gt; &lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/pre&gt;後者更勝一籌。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;一些小細節&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Breakpoint 回來啦。可以在啟動 Rails 的時候，將初始化動作寫到 initializers 裡面。&lt;br /&gt;&lt;br /&gt;這裡是這個投影片&lt;br /&gt;&lt;br /&gt;&lt;object type="application/x-shockwave-flash" data="https://s3.amazonaws.com:443/slideshare/ssplayer.swf?id=59001&amp;doc=a-peak-at-rails-20-3461" width="425" height="348"&gt;&lt;param name="movie" value="https://s3.amazonaws.com:443/slideshare/ssplayer.swf?id=59001&amp;doc=a-peak-at-rails-20-3461" /&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-2861264537853925517?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/2861264537853925517/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=2861264537853925517' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2861264537853925517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2861264537853925517'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/rails-20.html' title='Rails 2.0 預計的新特色'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-648334686922030742</id><published>2007-06-01T19:11:00.001+08:00</published><updated>2007-06-23T16:10:16.693+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='安裝'/><title type='text'>Fedora 7 安裝 Ruby on Rails</title><content type='html'>全新燒燙燙的 Fedora7 出來了，當然開始 test 他對 Ruby on Rails 有沒有問題啦（其實只是我愛好安裝新版本 Linux）。我最近發現到 Red Hat 系列對 Ruby on Rails 的支援度真是好，真的還蠻心動的。現在我們一個一個手動安裝吧。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;strong&gt;前置動作&lt;br /&gt;&lt;/strong&gt;  就是以下的動作是對於整個過程有幫助，但是不一定要做的方式。&lt;br /&gt;1. 修改 yum server ，指到國內義守的 server  &lt;blockquote&gt;vi /etc/yum.&lt;span&gt;repos&lt;/span&gt;.d/fedora.&lt;span&gt;repo&lt;/span&gt;&lt;br /&gt;&lt;span&gt;baseurl&lt;/span&gt; 改成&lt;br /&gt;&lt;span&gt;baseurl&lt;/span&gt;=http://ftp.isu.edu.tw/pub/Linux/Fedora/linux/core/$releasever/$basearch/os/&lt;br /&gt;&lt;br /&gt;vi /etc/yum.&lt;span&gt;repos&lt;/span&gt;.d/fedora-updates.&lt;span&gt;repo&lt;/span&gt;&lt;br /&gt;&lt;span&gt;baseurl&lt;/span&gt; 改成  &lt;span&gt;baseurl&lt;/span&gt;=http://ftp.isu.edu.tw/pub/Linux/Fedora/linux/core/updates/$releasever/$basearch/&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;2. 安裝 &lt;span&gt;gcc&lt;/span&gt; complier&lt;br /&gt;請打 gcc ，看你有沒有裝好 gcc compiler ，如果沒有的話，我們用暴力一點的方式  &lt;blockquote&gt;yum install gcc*  &lt;/blockquote&gt;3. 安裝 MySQL&lt;br /&gt;&lt;blockquote&gt;yum install mysql-server&lt;br /&gt;&lt;/blockquote&gt;&lt;strong&gt;開始安裝&lt;/strong&gt;&lt;br /&gt;1. 安裝 Ruby 以及 Ruby 的 MySQL Driver&lt;br /&gt;&lt;blockquote&gt;yum install ruby ruby-libs ruby-devel ruby-rdoc ruby-mysql ruby-irb&lt;br /&gt;&lt;/blockquote&gt; 2. 安裝 Ruby Gems&lt;br /&gt;太棒了，Ruby gems 也是內建就有的  &lt;blockquote&gt;yum install rubygems&lt;br /&gt;&lt;/blockquote&gt;3. 安裝 Rails   &lt;blockquote&gt;gem i rails -y  &lt;/blockquote&gt;4. 安裝 Mongrel&lt;br /&gt;如果沒裝 gcc ，這裡會失敗&lt;br /&gt;&lt;blockquote&gt;gem i mongrel&lt;br /&gt;&lt;/blockquote&gt;&lt;strong&gt;心得&lt;/strong&gt;&lt;br /&gt;Fedora7 安裝 Ruby on Rails 真的很方便，已經全部整合到 yum 裡面了，要快速架設 Server 應該不是任何問題。&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;同場加映，Lighttpd + Fastcgi 安裝方式&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;安裝 fastcgi &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;blockquote&gt;wget http://www.fastcgi.com/dist/fcgi-2.4.0.tar.gz&lt;br /&gt;cd fcgi-2.4.0&lt;br /&gt;./configure&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;/blockquote&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ruby Fastcgi&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;wget http://www.moonwolf.com/ruby/archive/ruby-fcgi-0.8.7.tar.gz&lt;br /&gt;ruby install.rb config -- --with-fcgi-include=/usr/local/include --with-fcgi-lib=/usr/local/lib&lt;br /&gt;ruby install.rb setup&lt;br /&gt;ruby install.rb install&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-648334686922030742?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/648334686922030742/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=648334686922030742' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/648334686922030742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/648334686922030742'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/06/fedora-7-ruby-on-rails.html' title='Fedora 7 安裝 Ruby on Rails'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-2330936248670511214</id><published>2007-05-31T20:55:00.000+08:00</published><updated>2007-05-31T21:37:53.337+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>Markaby：惡趣味的逆襲</title><content type='html'>有些東西你明知道是錯的，但是還是會去做，只是因為那樣做很爽。&lt;br /&gt;&lt;br /&gt;不是說你很邪惡，而只是因為有時候作壞事本身就是一件很有趣的事情。像是蹺課出去打撞球，像是上班偷懶，像是捉弄朋友....等等雖然明知道本身是不對的事情，但是依舊無法抗拒這種快感。第一次看到 &lt;a href="http://redhanded.hobix.com/inspect/markabyForRails.html"&gt;Markaby&lt;/a&gt;，心中的 OS 是「&lt;span style="font-weight: bold;"&gt;妖孽呀，這是網頁設計的邪道呀&lt;/span&gt;」。但是最近有機會碰到高手寫的 Markaby code ，頓時發覺有點沈溺其中無法自拔（&lt;span style="color: rgb(153, 51, 0);"&gt;果然是邪道，才會有毒品的快感&lt;/span&gt;）。或許這又是一個明知不對，但是又令人忍不住去碰的小誘惑。&lt;br /&gt;&lt;br /&gt;敝人小弟在下我曾經寫過&lt;a href="http://lightyror.thegiive.net/2006/09/htmlnew-template-system.html"&gt;HTML？New Template System ?&lt;/a&gt;，裡面有提到&lt;br /&gt;&lt;blockquote&gt;Ruby 統一全世界當然是一個美好的夢想，畢竟我是100%原汁的 Ruby 派。但是當你在商業應用上，版面設計通常交給美工，他們只需要會 Dreamweaver 之類的東西&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;這時候，難道你要教美工 Ruby 程式設計？&lt;/blockquote&gt;所以，除非 Dreamweaver 或是 Frontpage 支援 Ruby @@!，不然大家還是先把 HTML 當成網頁程式設計的最大公約數好了。&lt;/blockquote&gt;因為考慮到美工人員不太會去管程式，程式也沒這個 sense 去碰美工，所以所謂的 template 正道，就是「美工歸美工，程式歸程式」。基本要求是 HTML 版面跟 Rails 程式分開，美工好做事，程式也好修改。&lt;br /&gt;&lt;br /&gt;但是 Markaby 就是一個相當詭異的存在，他是一個使用 Ruby Code 來撰寫 html 的方式。他是一個 Rails Plugin ，安裝方式是&lt;br /&gt;&lt;pre&gt; script/plugin install http://code.whytheluckystiff.net/svn/markaby/trunk&lt;br /&gt;&lt;/pre&gt;rhtml 跟 markaby 是可以兩者並行的，請先將你的 markaby file 都從 .rhtml 改成 .mab 的名字，這樣 rails 就可以知道這是 markaby 的檔案了。&lt;br /&gt;&lt;br /&gt;撰寫範例是這樣&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;h&lt;span style="color: rgb(255, 0, 0);"&gt;1&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'Listing products'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;table.editor.classic &lt;strong&gt;do&lt;/strong&gt;&lt;br /&gt;tr &lt;strong&gt;do&lt;/strong&gt;&lt;br /&gt;  &lt;strong&gt;for&lt;/strong&gt; column &lt;strong&gt;in&lt;/strong&gt; Product.content_columns&lt;br /&gt;    th column.human_name&lt;br /&gt;  &lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;for&lt;/strong&gt; product &lt;strong&gt;in&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;@products&lt;/span&gt;&lt;br /&gt;  tr &lt;strong&gt;do&lt;/strong&gt;&lt;br /&gt;    &lt;strong&gt;for&lt;/strong&gt; column &lt;strong&gt;in&lt;/strong&gt; Product.content_columns&lt;br /&gt;      td product.send&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;column.name&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;    &lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;    td &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; link_to &lt;span style="color: rgb(0, 128, 0);"&gt;'Show'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;action &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'show'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;id &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; product &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;    td &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; link_to &lt;span style="color: rgb(0, 128, 0);"&gt;'Edit'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;action &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'edit'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;id &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; product &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;    td &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; link_to &lt;span style="color: rgb(0, 128, 0);"&gt;'Destroy'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;action &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'destroy'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;id &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; product &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;confirm &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'Are you sure?'&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;  &lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;link_to &lt;span style="color: rgb(0, 128, 0);"&gt;'Previous page'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;page &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;@product_pages.current.previous&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt; &lt;strong&gt;if&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;@product_pages.current.previous&lt;/span&gt;&lt;br /&gt;link_to &lt;span style="color: rgb(0, 128, 0);"&gt;'Next page'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;page &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;@product_pages.current.next&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt; &lt;strong&gt;if&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;@product_pages.current.next&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;br&lt;br /&gt;&lt;br /&gt;link_to &lt;span style="color: rgb(0, 128, 0);"&gt;'New product'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;action &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'new'&lt;/span&gt;&lt;/pre&gt;裡面有很多 html tag 跟 Ruby code，Rails helper。裡面看不到煩人的 &amp;lt;% %&amp;gt; 等符號，只有讓人興奮的 Ruby code。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;好處呢？&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;就是一個爽字形容，還有另外一種自己已經成為高手的錯覺。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;壞處呢？&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;你沒辦法用美工改好給你的 HTML code ，你必須要求美工使用 CSS 來做所有排版的工作，不然合作起來也非常累。另外一個壞處是，交接的時候交接的人會很不高興，這是哪門子的版面 code ，要我怎麼看呀。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;該不該用呢？&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;就實際面來說，沒有任何實用價值。但是你也知道，有些東西你明知道是錯的，但是還是會去做，只是因為他很爽。所以夜深人靜的某個夜晚，我依舊偷偷使用 Markaby 來寫我的某個小網頁 :p&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-2330936248670511214?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/2330936248670511214/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=2330936248670511214' title='27 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2330936248670511214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2330936248670511214'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/markaby.html' title='Markaby：惡趣味的逆襲'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>27</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-4782363803790495387</id><published>2007-05-28T17:23:00.001+08:00</published><updated>2007-05-31T20:47:33.648+08:00</updated><title type='text'>給寄信問我問題的朋友們</title><content type='html'>&lt;p&gt;我先說一下我現在 Email inbox 裡面的情況，我每天會收到 10 ~ 50封左右的問 Ruby on Rails 問題 Email，x 封左右的 Start up 合作信件，還不包含我工作相關信件。也就是說，你們寄給我的信件通常會在Email 大海中飄盪，運氣好我會看到，而且就算看到了，我通常抽不出時間解決。最慘的是，通常 10個問題有五個是重複的....................。&lt;br/&gt; &lt;/p&gt;&lt;p&gt;這個情況已經持續了三個月有了，我也不知道為了晚回 Email 道歉過幾百次了，為了解決這個情況，希望每個看我 Blog 朋友，如果有問題的話，可以到&lt;a href="http://www.javaworld.com.tw/jute/ruby.html"&gt; JavaWorld 的 Ruby 版&lt;/a&gt;上面發問，我會定期去那邊回答問題的，非常感謝。&lt;br/&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4782363803790495387?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/4782363803790495387/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=4782363803790495387' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4782363803790495387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4782363803790495387'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/blog-post.html' title='給寄信問我問題的朋友們'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-3355022073858710264</id><published>2007-05-28T16:21:00.001+08:00</published><updated>2007-05-28T16:21:28.162+08:00</updated><title type='text'>Event Driven Mongrel</title><content type='html'>&lt;p&gt;Mongrel 就大家所知道的，是採取 Thread 的方式來運作的，但是multi thread 在concurrent 大時 loading 會很重，要花很多時間處理很多 thread sync 問題。所以現在很多 Web Server ，包含 Lighty，Zeus 都是採用&lt;a href="http://en.wikipedia.org/wiki/Event-driven_programming"&gt; Event Driven&lt;/a&gt; 的方式來實做，Apache 現在也有&lt;a href="http://httpd.apache.org/docs/2.2/mod/event.html"&gt; Event Driven&lt;/a&gt; 的運作方式。&lt;/p&gt;  &lt;p&gt;Mongrel 現在也有人做&lt;a href="http://brainspl.at/articles/2007/05/12/event-driven-mongrel-and-swiftiply-proxy"&gt; Event Driven 的實做方式&lt;/a&gt;了，不過你得跟 Swiftiply 一起安裝。&lt;/p&gt;  &lt;blockquote&gt;&lt;p&gt;gem i swiftiply&lt;/p&gt;  &lt;/blockquote&gt;&lt;p&gt;然後啟動 Mongrel 就始用&lt;/p&gt;  &lt;blockquote&gt;&lt;p&gt;EVENT=1 mongrel_rails start&lt;/p&gt;  &lt;/blockquote&gt;&lt;p&gt;就可以啟動了。&lt;/p&gt;  &lt;p&gt;快不快的部份我現在還沒發現，但是至少跑到現在還沒掛點是個很好的事情。&lt;br/&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-3355022073858710264?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/3355022073858710264/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=3355022073858710264' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3355022073858710264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3355022073858710264'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/event-driven-mongrel.html' title='Event Driven Mongrel'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-6239058052142903436</id><published>2007-05-23T16:19:00.001+08:00</published><updated>2007-05-23T16:22:50.772+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>[ 書評 ] Ruby on Rails 專業網站案例實作</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_8vS0KjIsbko/RlP5qQEmjLI/AAAAAAAAAHw/GFHmUF2NxD0/s1600-h/image.jpeg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp0.blogger.com/_8vS0KjIsbko/RlP5qQEmjLI/AAAAAAAAAHw/GFHmUF2NxD0/s320/image.jpeg" alt="" id="BLOGGER_PHOTO_ID_5067668509986032818" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;對於我這樣不認真的人來說，要我寫 Testing 簡直是要了我的命，所以我從一開始看 Ruby on Rails 的時候，就完全沒碰 Testing 的部份。上次 UbiSunrise 的活動結束後，我還記得有觀眾告訴我&lt;/p&gt;  &lt;blockquote&gt;&lt;p&gt;Ruby on Rails 比 Java 好的地方就是 Testing&lt;/p&gt;  &lt;/blockquote&gt;&lt;p&gt;讓我霎時間一個大大的 shock 。到底 Ruby on Rails 的 Testing 有何精妙之處呢？&lt;/p&gt;  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;命運是好玩的，很快的這本 「&lt;a href="http://www.books.com.tw/exep/prod/booksfile.php?item=0010365587"&gt;Ruby on Rails 專業網站案例實作&lt;/a&gt;」就出現在我的身邊。這是 Beginning Ruby on Rails E-Commerce: From Novice to Professional 的翻譯本，從書名來看，這本書是介紹用 Ruby on Rails 來寫 E-Commerce 的書，但是翻到一半，他給了我一種「Beyound Java」的感覺，沒錯，又是一本內容不錯，但是書名取怪的書。如果要我重新定一個書名，我想取「使用 Ruby on Rails學習 Test-Driven Development」應該是一個很好的書名。&lt;/p&gt;  &lt;p&gt;沒錯，這是一本講解 Test-Driven Development 的良好教材，應該說，裡面有很多很棒的 Ruby on Rails Testing 範例 Code。並且開發方式真的是遵照 TDD 原則，先寫 Testing code ，再開始寫 real code。我從裡面的範例從頭到尾看到完，我享受了一頓真的很不錯的 Testing Tutorial。我從裡面學習很多很多 Testing 的技巧跟觀念。書的後半段還有介紹 &lt;a href="http://www.openqa.org/selenium/"&gt;Selenium&lt;/a&gt; 這個驗收測試的工具使用方式。真的是 Testing 的全套都 run 過一次，整本書算是一個完整的 Testing Tutorial。&lt;/p&gt;  &lt;p&gt;再來，最後面的部份其實收錄了不少 Enterprise 才需要的問題，像是 deploy，I18n，效能最佳化等等的議題，而且整理的還很不錯。&lt;/p&gt;  &lt;p&gt;最後，翻譯者功力很好，翻譯的不差，我那麼討厭看中文電腦書的人都覺得翻譯的真的順眼。「Convention over Configuration」 翻成「&lt;strong&gt;慣例優於組態&lt;/strong&gt;」這個翻譯是我看過目前為止，把 Convention over Configuration 翻譯的最簡短，也最不失真的翻譯方式。&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;要講缺點的話，當然也有。他不是一個初學者的書本，裡面的講解方式都是要對 Ruby on Rails 有一定基礎的人才能夠輕鬆的閱讀，講解基礎觀念的部份不多。再來就是書名很容易造成誤導，最好改個書名比較好。&lt;/p&gt;  &lt;p&gt;我還蠻喜歡這本書的。&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6239058052142903436?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/6239058052142903436/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=6239058052142903436' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6239058052142903436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6239058052142903436'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/ruby-on-rails.html' title='[ 書評 ] Ruby on Rails 專業網站案例實作'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_8vS0KjIsbko/RlP5qQEmjLI/AAAAAAAAAHw/GFHmUF2NxD0/s72-c/image.jpeg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-7669058008526249179</id><published>2007-05-17T23:01:00.001+08:00</published><updated>2007-05-17T23:04:40.648+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='depoly'/><title type='text'>把你的 Rails App 打包成 RPM Package</title><content type='html'>&lt;p&gt;剛剛看到 gigix 寫的 &lt;a href="http://gigix.thoughtworkers.org/articles/2007/04/28/create-rpm-for-your-rails-application"&gt;Create RPM For Your Rails Application&lt;/a&gt;，這是一個叫做 rpmpackager 的 rails plugin，目的是將你的 Rails App 打包成 RPM Package。我覺得這個東西假設配合&lt;a href="http://lightyror.thegiive.net/2007/05/rubyworks-001-release.html"&gt; RubyWorks&lt;/a&gt; ，是一個在 Fedora Like Linux 上面還算是不錯的 deploy 的好作法。&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;前置工作&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;在使用這個 plugin 之前，系統上面必須安裝而且設定好 &lt;a href="http://www.rpm.org/max-rpm-snapshot/rpmbuild.8.html"&gt;rpmbuild&lt;/a&gt; 這個工具。&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;安裝 plugin &lt;/strong&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;ruby script/plugin install http://rubyworks.googlecode.com/svn/trunk/rpmpackager/&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;設定&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;設定檔在 vendor/plugins/rpmpackager/config.yml 裡面，內容是&lt;br /&gt;&lt;/p&gt;  &lt;blockquote&gt;&lt;pre&gt;configuration:&lt;br /&gt;app_name:  app的名字&lt;br /&gt;description: 敘述&lt;br /&gt;license: Apache&lt;br /&gt;version: 1.2.1&lt;br /&gt;release: 1&lt;br /&gt;# RPM dependencies. separated with commas dependencies: openssl, mysql &amp;gt;= 5.0&lt;br /&gt;# 這裡敘述著 RPM 之間的 dependencies&lt;br /&gt;# 如果我要使用 openssl 跟 MySQL 5.0 以上的版本，就這樣寫&lt;br /&gt;# openssl, mysql&amp;gt;=5.0&lt;br /&gt;# 中間用 , 分開&lt;br /&gt;# gem dependencies and installation indecies&lt;br /&gt;# 0 for gems don't need selection&lt;br /&gt;# gem 之間的 dependencies ，0 代表不用，1 代表需要這個 gem package&lt;br /&gt;gems:&lt;br /&gt;  redcloth: 0&lt;br /&gt;  rcov: 1&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;打包 RPM&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;使用 rake rpm_package 來打包成 RPM ，他會將 RPM Package 放在 /usr/src/redhat/RPMS/i386/ 底下。而打包好的 RPM 會自動安裝到 /usr/local/lib/rails-apps/#{app_name} 底下。&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7669058008526249179?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/7669058008526249179/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=7669058008526249179' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7669058008526249179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7669058008526249179'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/rails-app-rpm-package.html' title='把你的 Rails App 打包成 RPM Package'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-1422028458244306459</id><published>2007-05-17T19:32:00.000+08:00</published><updated>2007-05-17T23:14:57.357+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='deploy'/><category scheme='http://www.blogger.com/atom/ns#' term='安裝'/><title type='text'>RubyWorks 0.0.1 Release</title><content type='html'>如果你覺得安裝所有的 Ruby on Rails 相關套件，並且將 Production Server系統設定好是一件很麻煩的事情嗎？或許你可以試試看&lt;a href="http://rubyworks.rubyforge.org/"&gt; RubyWorks&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;RubyWorks 是一個在 Red Hat Enterprise 或是 CentOS 上面的套件組合，他會幫你把所有 Production 環境下面的相關的 Ruby on Rails 套件跟 Server 套件一次安裝完成，並且提供一個馬上可以跑的 defulat config file，也就是說各位公司的技術長們不需要花時間去看那麼多 Production 設定方式，你已經有一個很堪用的 Production Ruby on Rails Server了。&lt;br /&gt;&lt;br /&gt;So，你還有理由不玩 Ruby on Rails嗎？&lt;br /&gt;&lt;br /&gt;我們看看怎麼安裝 RubyWorks，因為我沒有 Red Hat Enterprise Server，所以我只 Test CentOS。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;前置作業&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;RubyWorks 因為好像還沒進去 yum 資料庫，所以我們還是得必須告訴 yum 哪裡有 RubyWorks 的 Package，如果已經進去yum repo了，就好像不需要這個動作了。&lt;br /&gt;&lt;br /&gt;如果你像我一樣，是個不求甚解，只求可以 Work 的人，就這樣打就好了。&lt;br /&gt;&lt;blockquote&gt;wget http://rubyworks.rubyforge.org/public_key.txt   &lt;div class="code"&gt;sudo rpm --import public_key.txt&lt;br /&gt;&lt;div class="code"&gt;wget http://rubyworks.rubyforge.org/RubyWorks.repo&lt;/div&gt; &lt;div class="code"&gt;cp RubyWorks.repo /etc/yum.repos.d/&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div class="code"&gt;&lt;div class="code"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;YUM 安裝 Ruby Works&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;直接用 gem 安裝&lt;br /&gt;&lt;blockquote&gt;yum install rubyworks&lt;/blockquote&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;然後.....裝好了。&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;請連線到 http://localhost:3001/ 的地方，你一定會看到一個很熟悉的畫面。是的，Ruby on Rails 已經跑起來了，還是用 Haproxy 幫你跑的。不過這裡要講的是，因為他的取向不是 development server，而是 production server，所以他並不會安裝 Rails 的 gem package，而是直接將 rails 放在 &lt;span style="font-style: italic;"&gt;/usr/rails/vender/rails &lt;/span&gt;裡面。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Rubyworks 安裝表&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;RubyWorks 一共會幫你安裝&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;ruby&lt;/strong&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;ruby-devel&lt;/strong&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;rubygems&lt;/strong&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;haproxy&lt;/strong&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;     &lt;strong&gt;monit&lt;/strong&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="font-weight: bold;"&gt;mongrel&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;rubyworks&lt;/strong&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;並且幫你設定好 HAProxy ，跑在 3001 Port，Mongrel 跑在 3002~3005 Port，monit 跑在 2812 port。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Rubyworks 詳細位置表&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;詳細的安裝位置是在&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;/usr/bin/ruby/&lt;/code&gt;：Ruby 所在地&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;/usr/lib/ruby/&lt;/code&gt; ：Ruby libraries&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;/usr/lib/ruby/1.8/&lt;/code&gt; ：Ruby standard library&lt;/li&gt;&lt;li&gt;&lt;code&gt;/usr/lib/ruby/gems/1.8/gems/&lt;/code&gt; ：所有安裝的 Ruby gems Package&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;/usr/bin/monit&lt;/code&gt; ：monit 執行檔&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;/etc/init.d/monit&lt;/code&gt;：monit的啟動 script，所有的 server 都會在 monit 啟動的時候，也順便幫你啟動好了（Mongrel，Haproxy）&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;/usr/bin/haproxy&lt;/code&gt; ：HAProxy 執行檔&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;/usr/bin/mongrel_rails&lt;/code&gt; ：Mongrel&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;/etc/rails/&lt;/code&gt; ：configuration files&lt;/li&gt;&lt;li&gt;&lt;code&gt;/var/rails/&lt;/code&gt; ：所有 Deamon  的 .pid files&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;/usr/rails/&lt;/code&gt; ：Rails app code 所在地。 &lt;/li&gt;&lt;li&gt;&lt;code&gt;/var/log/monit.log&lt;/code&gt; ：Monit 的 log&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;/var/log/haproxy.log&lt;/code&gt; ：HAProxy log&lt;/li&gt;&lt;li&gt;&lt;code&gt;/usr/rails/log/&lt;/code&gt;：Mongrels and Rails 的 log&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;                           &lt;/div&gt;&lt;br /&gt;&lt;b&gt;延伸閱讀&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://rubyworks.rubyforge.org/"&gt;RubyWorks 網頁&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://gigix.thoughtworkers.org/articles/2007/05/16/rubyworks-initial-release"&gt;RubyWorks 0.0.1 Released&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1422028458244306459?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/1422028458244306459/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=1422028458244306459' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1422028458244306459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/1422028458244306459'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/rubyworks-001-release.html' title='RubyWorks 0.0.1 Release'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-9197723315434026886</id><published>2007-05-15T23:33:00.001+08:00</published><updated>2007-05-15T23:36:26.431+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>心愛的 Object 變心啦</title><content type='html'>&lt;p&gt;剛剛發現一個很有趣的事情，寫 code 的時候，有兩個 Model ：Person 跟  Setting ，他們呈現 1: 1 關係。結果當我想要創立一個新的 Person 的時候，為了希望能夠簡化設計，我就將其中一個人 a 當作預設值，每個新增 Person 的 Setting 直接 copy 一份過去，所以我就這樣寫&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;a &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; Person.find&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;b &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; Person.new&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;name &lt;span style="color: rgb(68, 68, 255);"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'lala'&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;b.setting &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; a.setting&lt;br /&gt;b.save&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;我真的沒想太多，但是慘劇就發生了。a.setting 就變心到 b 去了。&lt;/p&gt;  &lt;p&gt;&amp;gt;&amp;gt; a = User.find 1&lt;br /&gt;=&amp;gt; #&amp;lt;Person:0x371ee38 @attributes={"updated_at"=&amp;gt;"2007-05-15 22:55:45", "nname"=&amp;gt;"hemidemi lala", "type"=&amp;gt;"GroupAdmin", "id"=&amp;gt;"1", "password"=&amp;gt;"123", "created_at"=&amp;gt;"2007-05-09 00:46:35"}&amp;gt;&lt;br /&gt;&amp;gt;&amp;gt; a.setting&lt;br /&gt;=&amp;gt; nil&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;也就是他自動的幫你把 a.setting 的 model 裡面的 foreign key 指定到新增的 b ，然後一去不回頭。要預防 object 變心方法也很簡單，就是幫新人找一份完全一模一樣的新伴侶即可。&lt;/p&gt;  &lt;pre&gt;a &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; Person.find&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;b &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; Person.new&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;name &lt;span style="color: rgb(68, 68, 255);"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'lala'&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;b.setting &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; a.setting.clone&lt;br /&gt;b.save&lt;/pre&gt; &lt;p&gt;Clone 是 &lt;a href="http://www.rubycentral.com/book/ref_c_object.html"&gt;Ruby object&lt;/a&gt; 裡面的 method ，作法就是 copy 一份新的 instance。雖然在實際使用上， 其實 clone 並不會直接 new 一份真的 instance，而是 new 一個 object ，然後將裡面 attribute 直接 reference 過去&lt;span style="color: rgb(153, 51, 0);"&gt;[註1]&lt;/span&gt;。但是在 ActiveRecord 裡面使用，因為是直接寫回資料庫，所以就完全沒副作用，所以可以盡量大方的使用。&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: rgb(153, 51, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;註1&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;irb(main):001:0&amp;gt; class Klass&lt;br /&gt;irb(main):002:1&amp;gt;    attr_accessor :str&lt;br /&gt;irb(main):003:1&amp;gt; end&lt;br /&gt;irb(main):004:0&amp;gt; s1 = Klass.new  =&amp;gt; #&amp;lt;Klass:0x89e7c&amp;gt;&lt;br /&gt;irb(main):007:0&amp;gt; s1.str = 'Hello'   =&amp;gt; "Hello"&lt;br /&gt;irb(main):008:0&amp;gt; s2 = s1.clone    =&amp;gt; #&amp;lt;Klass:0x79d38 @str="Hello"&amp;gt;&lt;br /&gt;irb(main):009:0&amp;gt; s1.object_id      =&amp;gt; 282430&lt;br /&gt;irb(main):010:0&amp;gt; s2.object_id      =&amp;gt; 249500&lt;br /&gt;irb(main):011:0&amp;gt; s1.str.object_id =&amp;gt; 261360&lt;br /&gt;irb(main):012:0&amp;gt; s2.str.object_id =&amp;gt; 261360&lt;/p&gt;  &lt;p&gt;我們可以發現到 s1 跟  s2 其實是兩個不同的 object ，但是裡面的 attribute str 卻是同一個 object。&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-9197723315434026886?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/9197723315434026886/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=9197723315434026886' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/9197723315434026886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/9197723315434026886'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/object.html' title='心愛的 Object 變心啦'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-3584990633190893432</id><published>2007-05-15T18:10:00.001+08:00</published><updated>2007-05-15T18:19:23.618+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><title type='text'>jRuby 代表的意義</title><content type='html'>&lt;p&gt;最近看到&lt;a href="http://midnightrubyist.blogspot.com/2007/05/codegear-unveils-ruby-on-rails-ide.html"&gt;這篇文章&lt;/a&gt;，裡面有一個問題&lt;/p&gt;  &lt;blockquote&gt;&lt;p&gt;請問在JVM上跑Rails要幹嘛？&lt;/p&gt;  &lt;/blockquote&gt;&lt;p&gt;我在這邊講一下為什麼我對 jRuby 的期望那麼深。&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;我們看一下一段 code ，這是從 &lt;a href="http://www.oreilly.com/catalog/rubyckbk/"&gt;Ruby Cookbook&lt;/a&gt; 抓下來的範例&lt;br /&gt;&lt;/p&gt;  &lt;pre&gt;&lt;span style="color: rgb(68, 68, 68);"&gt;#!/usr/bin/env jruby&lt;br /&gt;# random.jrb&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;require&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'java'&lt;/span&gt;&lt;br /&gt;include_class &lt;span style="color: rgb(0, 128, 0);"&gt;'java.util.Random'&lt;/span&gt;&lt;br /&gt;r &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; Random.new&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;123&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;puts&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"Some random number &lt;span style="color: rgb(32, 64, 160);"&gt;#{r.nextInt % 10}&lt;/span&gt;"&lt;/span&gt;&lt;br /&gt;r.seed &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;456&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;puts&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"Another random number &lt;span style="color: rgb(32, 64, 160);"&gt;#{r.nextInt % 10}&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;啟動的時候會出現這樣的結果&lt;/p&gt;  &lt;blockquote&gt;&lt;p&gt;$ jruby random.jrb&lt;br /&gt;Some random number 9&lt;br /&gt;Another random number 0&lt;br /&gt;&lt;/p&gt;  &lt;/blockquote&gt;&lt;p&gt;我們仔細看到這段 jruby code，他是完完全全的 Ruby 程式，但是他使用 Random Number lib 是使用 JAVA lib。這代表&lt;strong&gt; jRuby 讓 Ruby 可以隨意呼叫 Java Lib&lt;/strong&gt; 。&lt;/p&gt;  &lt;p&gt;Ruby 被 chanllenge 的其中一個地方就是「Third Party Lib 不足」，這個通常需要時間跟社群的持續的累積，但是如果直接使用 Java Lib，那不就是一個「別重新造輪子」的最好例子嗎？jRuby 不也就很直接的解決掉 Ruby Third Party Lib 不足的問題嗎？當然啦，jRuby 還有很多好處，但是最直接，也是最令人興奮的好處就是可以直接使用 Java Lib。&lt;br /&gt;&lt;/p&gt;  &lt;!-- technorati tags begin --&gt;&lt;p style="font-size: 10px; text-align: right;"&gt;technorati tags:&lt;a href="http://technorati.com/tag/jruby" rel="tag"&gt;jruby&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-3584990633190893432?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/3584990633190893432/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=3584990633190893432' title='7 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3584990633190893432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3584990633190893432'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/jruby.html' title='jRuby 代表的意義'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-8399276271050702525</id><published>2007-05-10T16:25:00.000+08:00</published><updated>2007-05-11T06:31:25.975+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='scale'/><title type='text'>Twitter , Rails , Scalibility...More</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_8vS0KjIsbko/RkOYhmklRqI/AAAAAAAAAHc/aNN23hx7rhQ/s1600-h/twitter.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp0.blogger.com/_8vS0KjIsbko/RkOYhmklRqI/AAAAAAAAAHc/aNN23hx7rhQ/s320/twitter.png" alt="" id="BLOGGER_PHOTO_ID_5063058109151659682" border="0" /&gt;&lt;/a&gt;&lt;a href="http://twitter.com/"&gt;Twitter &lt;/a&gt;是一個最近非常熱的 Web Site，他們主要是可以利用簡訊，網頁更新自己的近況。Twitter 的開發者 Alex Payne 在&lt;a href="http://www.radicalbehavior.com/5-question-interview-with-twitter-developer-alex-payne/"&gt;接受訪問的時候&lt;/a&gt;，拋出了一個震撼性的議題&lt;br /&gt;&lt;blockquote&gt;Rails Scalibility 到底好不好的問題&lt;br /&gt;&lt;/blockquote&gt;夠震撼吧。我發現到很多人都開始發表了 「Rails 遇到效能上的問題...」。看到只能說，這是 Rails 社群第一個大挑戰，但是請不要太過武斷就直接認為是 Rails 的問題。如果大家仔細了解這個事情的情況，就可以大略推估應該是 Twitter Team 成功的太快，整個 team 的成長跟不上網站的成長速度。我們來看看到底事情的始末。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;故事開始&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Alex Payne 是 Twitter Team 其中一員，他接受了&lt;a href="http://www.radicalbehavior.com/"&gt; Radical Behavior &lt;/a&gt;的訪問，當被問到 Ruby on Rails 如何應付高速成長的流量時，他指出他認為 Ruby on Rails 有不少 Scability 的議題，Alex 的論點如下&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Ruby is slow&lt;/li&gt;&lt;li&gt;Rails 一次不能 connection multi database&lt;/li&gt;&lt;li&gt;Rails 有些東西 component，性能消耗太大，必須不去使用&lt;/li&gt;&lt;/ol&gt;此話一出，當然引起了 Rails 社群的積極辯護，跟其他語言社群基於「良心」的建議。當然，我們 Rails 社群當中的老大DHH ，也不落人後的提出&lt;a href="http://www.loudthinking.com/"&gt;相關的建議&lt;/a&gt;。DHH 似乎覺得 Twitter 有點太過於懶惰了點，Twitter 比很多人幸運，有機會碰到那麼大的流量，那就該好好的想辦法處理相關的問題。而不是等著別人幫你解決你應該解決的問題。Open source 的成功，是來自使用者遇到相關的問題，並且解決他，回報給社群，這樣社群才會繼續壯大起來。&lt;br /&gt;&lt;blockquote&gt;Second, when you work with open source and you discover new requirements not met by the software, it's your shining opportunity to give something back. Rather than just sit around idle waiting for some vendor to fix your problems, you get the unique chance of being a steward of your own destiny. To become a participant in the community rather than a mere spectator. This is especially true with frameworks like Rails that are implemented in high-level languages like Ruby. The barriers to contribution are exceptionally low&lt;br /&gt;&lt;/blockquote&gt;至於 Rails 一次連結到多個 DB 的問題，老實說，這根本不是問題，Dr. Nick 早就提出了&lt;a href="http://magicmodels.rubyforge.org/magic_multi_connections/"&gt;Magic Multi Connections&lt;/a&gt;，可以有效解決這個問題。至於 Twitter 團隊是不知道這個東西，還是試過這個 Plugin 之後發現不夠用呢？&lt;a href="http://www.infoq.com/news/2007/04/twitter-controversy"&gt;InfoQ 訪問了 Twitter 另外一個開發者 Blaine Cook&lt;/a&gt;，說到 Dr. Nic 的 Plugin 很棒，很有幫助， Blaine Cook 表示目前 Twitter 的 DB Connection 是 600 req/sec，雖然很高，但是現在 Twitter 沒有暫時 DB 的問題。（&lt;span style="font-style: italic; color: rgb(204, 102, 0);"&gt;那之前 alex 不是質疑說他們的問題是在 DB ? 到底 Twitter Bottleneck 在那裡？有點不了解他們的 Point 。&lt;/span&gt;）&lt;blockquote&gt;"Dr. Nic's approach is a great first step, and adds some welcome helpers to selecting from a number of database connections." but noted that "Twitter isn't currently database bound, and won't be for a while yet"&lt;/blockquote&gt;這時 Dr. Nic 也出來&lt;a href="http://www.infoq.com/news/2007/04/twitter-controversy"&gt;打圓場&lt;/a&gt;了，他說「Twitter 已經貢獻了 Jabber API 了」，其實不用苛求太多啦。&lt;br /&gt;&lt;blockquote&gt;The guys at Twitter have already contributed code to Ruby community (Jabber API)&lt;br /&gt;&lt;/blockquote&gt;話說回來，Twitter Team 也似乎感受到 Rails 社群對他們處於制高點的期待，也開始對社群做出了幫助。Blaine Cook 在 SDForum 發表了 「&lt;a href="http://www.slideshare.net/Blaine/scaling-twitter"&gt;Scaling Twitter&lt;/a&gt;」，裡面提到許多他們的問題以及解決方式。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;進入討論&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;OK ，我們已經把故事講完了，現在討論正經點的事情。&lt;br /&gt;&lt;blockquote&gt;到底是 Twitter 技術上不夠厲害，或是 Rails 不夠 Scalibility？&lt;br /&gt;&lt;/blockquote&gt;我認為這個 case 無法認定那一個結論是正確的。我們看看 twitter 的流量成長&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_8vS0KjIsbko/RkMDzmklRpI/AAAAAAAAAHA/6ReQPP_fFr0/s1600-h/%E6%93%B7%E5%9C%96_1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_8vS0KjIsbko/RkMDzmklRpI/AAAAAAAAAHA/6ReQPP_fFr0/s320/%E6%93%B7%E5%9C%96_1.png" alt="" id="BLOGGER_PHOTO_ID_5062894591156766354" border="0" /&gt;&lt;/a&gt;很明顯的，Twitter 在 2007 年的流量是一個暴發戶的成長方式，通常網站遇到了這樣突然爆增的流量，原本編制的 RD 跟網管應該都完全無法應付吧，那麼一時之間無法解決也是非常正常的事情。所以，他們應該也不是太懶惰，只是成功的太突然，沒辦法吃下來。&lt;br /&gt;&lt;br /&gt;再來，根據Blaine Cook 在 SDForum 發表的「&lt;a href="http://www.slideshare.net/Blaine/scaling-twitter"&gt;Scaling Twitter&lt;/a&gt;」投影片，他們一共有 180 Mongrel Instances，但是卻只有使用兩個 DB Server，這似乎完全不符合一般大網站所遇到的情況（就是一海票的 DB Server，每個 table 都是橫切縱切隨便切）。當然我們不排除 twitter 的  application 型態其實並不需要太多 DB 的 request ，不過180 Mongrel Instant 居然只有 兩台 DB Server ，未免也太少了點，也不符合比例原則。&lt;br /&gt;&lt;br /&gt;Twitter 是 host 在 &lt;a href="http://www.joyent.com/"&gt;joyent&lt;/a&gt; 上面的，像這種有一定規模的網站公司居然沒有自己專屬的系統管理者，光是這點這就看出 Twitter 成長真的太快了。一般來說，Web Host 很難做到專門為某個 Service 最佳化吧。Scalibility 本來就是軟體開發者跟系統管理者並肩合作的工程，Twitter 該多請幾個系統設計師摟。&lt;br /&gt;&lt;br /&gt;至於 Ruby 是不是真的太慢，Rails 是不是真的不夠 Scalibilty呢？&lt;br /&gt;&lt;br /&gt;這個問題我也不知道，畢竟我沒 run 過那麼大的 site，而我看到的 site 都是效率很不錯的。LAMP 發展了很久，Java 跟 Python 發展了很久，他們擁有 Ruby and Rails 社群無法比擬的成熟度，這是不爭的事實。但是，為什麼 Rails 會讓那麼多人趨之若騖，而非那些其他的語言呢？&lt;br /&gt;&lt;blockquote&gt;那是因為 Ruby on Rails 擁有一些別人沒有的東西。而那些東西是很難被取代的。&lt;/blockquote&gt;&lt;br /&gt;今天這件事情沒有誰對誰錯，Twitter 點出這個議題，並且強調這個議題的重要性，Rails 社群接收到 Twitter 的訊息，大家一起幫忙解決，這是一個良性的溝通。我相信 Scalibility 是可以被克服的議題，也是值得一起去加油的議題。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;延伸閱讀&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.radicalbehavior.com/5-question-interview-with-twitter-developer-alex-payne/"&gt;Alex 訪談原文：5 Question Interview with Twitter Developer Alex Payne&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.loudthinking.com/"&gt;DHH 回應&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.infoq.com/news/2007/04/twitter-controversy"&gt;InfoQ 原文&lt;/a&gt;，&lt;a href="http://www.infoq.com/cn/news/2007/04/twitter-controversy"&gt;簡體中文翻譯&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ria.richtechmedia.com/2007/04/22/rails-in-trouble/"&gt;d.cat blog 對這件事情的討論&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8399276271050702525?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8399276271050702525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8399276271050702525'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/twitter-rails-scalibilitymore.html' title='Twitter , Rails , Scalibility...More'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_8vS0KjIsbko/RkOYhmklRqI/AAAAAAAAAHc/aNN23hx7rhQ/s72-c/twitter.png' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-3543473315594291418</id><published>2007-05-06T20:25:00.000+08:00</published><updated>2007-05-06T20:35:54.609+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='src_present'/><title type='text'>coderay</title><content type='html'>事情很簡單，就是每次我貼程式碼都覺得有很大的困擾，因為不只排版很麻煩，highlight 的問題更是折騰。我之前曾經改寫過一個用 ruby 寫成的 nopaste, 他是呼叫外部 highlight 的程式，查了一下，是這個：&lt;a href="http://www.andre-simon.de/" target="blank"&gt;http://www.andre-simon.de/&lt;/a&gt;. 關於那個 nopaste 我就不多提了，寫得很爛，沒什麼營養。（這也是我想改寫的原因）&lt;br /&gt;&lt;br /&gt;後來你也知道，我三分鐘熱度很嚴重，所以只改到一半就沒繼續做下去了。&lt;br /&gt;&lt;br /&gt;過了一段時間，我看到了 Lighty RoR 上的〈&lt;a href="http://lightyror.thegiive.net/2006/10/syntax-highlight.html" target="_blank"&gt;Syntax Highlight 套件&lt;/a&gt;〉，讓我重新想起這件事，希望以後能有個好 highlight 方式。於是我灌了 &lt;a href="http://rubyforge.org/projects/syntax/" target="_blank"&gt;syntax gem&lt;/a&gt;, &lt;a href="http://rubyforge.org/projects/coderay/" target="_blank"&gt;coderay gem&lt;/a&gt;, 還有 &lt;a href="http://rubyforge.org/projects/text-highlight/" target="_blank"&gt;highlight gem&lt;/a&gt;. 結果那次到底發生了什麼事，其實我也忘了。只記得好像是稍微試過之後就放到一邊去了吧。&lt;br /&gt;&lt;br /&gt;今天我又想起這件事，所以又重新找起套件來了。看來看去，syntax 和 highlight 好像都不怎麼好用。最後我終於又試到了 coderay. 這次發現 coderay 相當好用，應該不用繼續找下去了。&lt;br /&gt;&lt;br /&gt;gem install coderay&lt;br /&gt;coderay -ruby -span &amp;lt; input.rb &amp;gt; output.rb.txt&lt;br /&gt;這樣可以產生適合直接貼到支援 HTML/CSS 文章中的 HTML+CSS code.&lt;br /&gt;coderay -ruby -page &amp;lt; input.rb &amp;gt; output.rb.html&lt;br /&gt;這樣會直接產生一個完整的 XHTML 1.0 的頁面，相當方便。&lt;br /&gt;coderay -ruby -html &amp;lt; input.rb &amp;gt; output.rb.html&lt;br /&gt;如此產生出來的 CSS 會是用 class 的形式，適合原本就有 CSS 檔的地方。&lt;br /&gt;&lt;br /&gt;（補充：另外除了 page 以外，span 和 html 視情況需要在前後加上 pre tag, 也許這部份可以再稍微 hack 一下使之不用加 pre tag, 省得事情變得更麻煩。）&lt;br /&gt;&lt;br /&gt;沒錯，最大的好處就是直接用 command line 就好了，不用寫 ruby 程式。其他所支援的語法，在 lib/coderay/scanners 中可以找到，就我現在手上的 0.7.4.215 版中有：&lt;br /&gt;&lt;br /&gt;c, delphi, html, nitro_xhtml, plaintext, rhtml, ruby, xml&lt;br /&gt;&lt;br /&gt;擴充容易，自己去寫 you_want.rb 丟到 scanners 中就可以使用了。至於輸出格式，在 lib/coderay/encoders 中可以找到，同版本中有：&lt;br /&gt;&lt;br /&gt;count, div, html, null, page, span, statistic, text, tokens, xml, yaml&lt;br /&gt;&lt;br /&gt;別問我是什麼意思，沒試過我也不知道。不過 statistic 是產生報表，這不小心試過 XD 還有這也和上面一樣，擴充容易，自己寫 encoders 就可以用自己要的輸出格式。至於在 ruby 程式中呼叫 coderay, 這當然沒問題了，用法自己找，我懶得試了。唯一可惜的是 license 是 GPL 吧，我不確定我可不可以把他拉到 &lt;a href="http://ludy.rubyforge.org/" target="_blank"&gt;ludy&lt;/a&gt; 而不用讓 ludy 用 GPL 釋出。不過沒差，這程式內容還滿多的，我應該沒時間好好去改他。乖乖地用&lt;br /&gt;就好了。&lt;br /&gt;&lt;br /&gt;除此之外，還找到 &lt;a href="http://rubyforge.org/projects/rhighlight/" target="_blank"&gt;rhighlight&lt;/a&gt;, 是上面提到的那個 &lt;a href="http://www.andre-simon.de/" target="blank"&gt;highlight&lt;/a&gt; 程式的 binding. 我想這也應該滿值得一試的，但既然先發現 coderay 堪用了，也懶得繼續試，就先 note 起來就好。除此之外，還有 &lt;a href="http://rubyforge.org/projects/sourcecode2html/" target="_blank"&gt;sourcecode2html&lt;/a&gt;, 不過這個看來還在開發中。&lt;br /&gt;&lt;br /&gt;2007.05.06 godfat 真常&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-3543473315594291418?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/3543473315594291418/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=3543473315594291418' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3543473315594291418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3543473315594291418'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/coderay.html' title='coderay'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-320777871565762012</id><published>2007-05-06T09:46:00.000+08:00</published><updated>2007-05-06T10:43:51.224+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ide'/><title type='text'>[News] Rails IDE 近況</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Apatana&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Apatana 自從跟 RadRails 整合後，最新出的第一個整合版本終於出了，下載點&lt;a href="http://www.aptana.com/download_rails_rdt.php"&gt;在這裡&lt;/a&gt;。不過 JavaEye 上面的群眾&lt;a href="http://www.javaeye.com/topic/73189"&gt;哀鴻遍野&lt;/a&gt;，大家發現整合的版本好像還不是很好，畢竟是 First Beta 版本，有很多問題是必然的:p  想當初 Lighty 1.5 的前幾個 Beta 版本不知道讓我出現多少次 CPU 100 %的情況。所以還是建議，可以先玩玩 Apatana Rails ，但是如果牽涉到正事的話，還是先用 RadRails 好了。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Eclipse&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.eclipsedltk.org/"&gt;Eclipse DLTK&lt;/a&gt; for Ruby 方便 Eclipse 使用者寫 Ruby，而道喜的技術日記也發表了一篇 &lt;a href="http://www.hhtong.com/blog1/articles/2007/05/05/tools-dltk-20070505"&gt;Ruby语言开发工具：Eclipse官方开发Ruby语言Editor&lt;/a&gt;，裡面講解 Windows 下面如何使用 Eclipse 開發  Ruby  程式。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-320777871565762012?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/320777871565762012/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=320777871565762012' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/320777871565762012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/320777871565762012'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/aptana-rails-ide.html' title='[News] Rails IDE 近況'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-8466282272082662343</id><published>2007-05-05T17:16:00.000+08:00</published><updated>2007-05-05T17:49:05.781+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>script/plugin</title><content type='html'>well, 由於我跟 Rails 不熟，所以很多地方只能憑空臆測，如果有誤也望請指點。很多跟 Rails 有直接關係的細節我也難以深究，所以大概只能從 Ruby 的角度看下去。總而言之呢，Rails 的 plugin 比起 rubygems 還更要簡單得多，根本沒有任何需要設定的部份，只要把目錄開好就可以輕易使用了。目錄結構大約是：&lt;br /&gt;&lt;br /&gt;init.rb&lt;br /&gt;install.rb&lt;br /&gt;lib/*.rb&lt;br /&gt;test/*.rb&lt;br /&gt;&lt;br /&gt;init.rb 是 Rails 在 load up 時會執行的部份，所以 plugin 要把 init up 的程式碼放到這邊，例如最常見的恐怕是：&lt;br /&gt;ActiveRecord::Base.send(:include, OOO)&lt;br /&gt;這邊使用 send 而不是直接用 . 的緣故是 include 本身是 private method, 用 . 的會有 NoMethodError. 不過我建議可能可以考慮使用 __send__ 而非 send, 因為有些 class 的 send 有被 override, 一不小心可能會有未預期的錯誤。（雖然應該一看就知道會是出什麼問題就是了）&lt;br /&gt;&lt;br /&gt;install.rb 則是在安裝時才會執行的程式，例如使用 script/plugin install OOO 就會先執行此 install.rb, 而日後不管何時使用此 plugin 時，install.rb 都不會再被執行。這部份可能會放的程式碼也許是會動到目錄結構的程式，例如在 app/models 下寫入 OOO_plugin.rb, 像這種只需要在安裝時執行一次即可。這樣做有什麼好處呢？我想感覺就有點像 script/generate OOO_plugin 的感覺吧。&lt;br /&gt;&lt;br /&gt;至於 lib/ 則會自動加入 load path, 這部份跟 rubygems 裡 gemspec 裡的 s.require_path = 'lib' 是相同的概念。test/ 的部份也和 rubygems 相同。&lt;br /&gt;&lt;br /&gt;接下來還有什麼好講的嗎？有的，參考〈&lt;a href="http://lightyror.thegiive.net/2007/04/actsastaggable-plugin.html"&gt;acts_as_taggable Plugin 使用方式&lt;/a&gt;〉一文，可以發現 acts_as_taggable.rb 寫得相當複雜，這當然是有原因的。我參考了官方網站裡跟 plugin 有關的&lt;a href="http://wiki.rubyonrails.org/rails/pages/Plugins" target="_blank"&gt;系列文章&lt;/a&gt;，發現 ActsAsOOO 是個相當常見的 plugin 模式，其中似乎有某種 pattern 在其中…。就是 ClassMethods, SingletonMethods, 與 InstanceMethods.&lt;br /&gt;&lt;br /&gt;這樣做的原因很簡單，就只是加強模組化與避免名稱污染，所以多繞了幾個圈。在這種模式的做法下，ActiveRecord::Base 所多出來的 method 只有 acts_as_taggable. 而當你在寫 class MyModel &lt; ActiveRecord::Base; acts_as_taggable; end 時，只有 MyModel 多出 class method =&gt; find_tagged_with, instance methods =&gt; tag_with, tag_list. 而不是整個 ActiveRecord::Base 都多出這些 methods.&lt;br /&gt;&lt;br /&gt;其實這做法也有點像 meta-programming, 只不過是用 mixin 的形式。在前一陣子裡，由於我搞不太清楚 include 與 extend 的差異，所以調查了一下，並做了些&lt;a href="http://www.godfat.idv.tw/viewtopic.php?t=361" target="_blank"&gt;筆記&lt;/a&gt;：（我知道多半連不上，所以 copy 一份到這）&lt;br /&gt;&lt;br /&gt;=begin&lt;br /&gt;2007.02.13&lt;br /&gt;&lt;br /&gt;include 將 module 內的所有 method 原封不動拿過來，extend 則是在原本的 method 前面多加個 self. 即 class C 內，寫 include M 則追加 instance method. 如果寫 extend M 則追加 class method.&lt;br /&gt;&lt;br /&gt;module 內也可以使用 include 與 extend, 結果同 class. include 為 instance level, extend 為 class level. 基本上這兩樣東西是很接近的。至於 module level 的 method, 則不受 include 也不受 extend 影響。其實跟 meta-programming 很像。&lt;br /&gt;&lt;br /&gt;module M&lt;br /&gt;  def m; end      # 只能由 include 或 extend 取用&lt;br /&gt;  def self.m; end # 只能用 M.m 來呼叫&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class C&lt;br /&gt;  include C # 獲得 instance method m&lt;br /&gt;  extend C  # 獲得 class method m&lt;br /&gt;end&lt;br /&gt;=end&lt;br /&gt;&lt;br /&gt;除此之外，module 還有個特別的東西叫 &lt;a href="http://www.ruby-doc.org/core/classes/Module.html#M001665" target="_blank"&gt;module_function&lt;/a&gt;, 這東西我還沒仔細研究，但初步認識的結果是，他會造成指定的 method 同時定義 def m; end 與 def self.m; end 詳細的內容可以當成讀者練習，呵。(雖然其實可能就只是這樣而已)&lt;br /&gt;&lt;br /&gt;回到 acts_as_taggable, 在 module Taggable 中唯一的 method 是：&lt;br /&gt;def self.included(base)&lt;br /&gt;  base.extend(ClassMethods)&lt;br /&gt;end&lt;br /&gt;這個相信大家都很熟了，就是指當此 module 被 include 時會執行的 method, 有點 hook 的概念。這裡的 base 就是 includer, who include this module. 在 Taggable 中，當然就是 ActiveRecord::Base 了。extend 上面看到了，會促使該 class 擁有此 module 中所有的 method 成為 class method, 所以 ActiveRecord::Base 多了個 acts_as_taggable 為 class method. 如此一來，就能寫：&lt;br /&gt;class MyModel &lt; ActiveRecord::Base&lt;br /&gt;  acts_as_taggable&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;其實我覺得這樣實作有點過於複雜，我會比較喜歡這種形式：&lt;br /&gt;class ActiveRecord::Base&lt;br /&gt;  def self.acts_as_taggable&lt;br /&gt;    # ...&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;這樣就一目了然了。缺點當然就是會比較難將此 method 丟給其他人用，例如假設哪天有了一個 class 是 PassiveRecord, 也想將 act_as_taggable 丟給他使用，可能就必須 &lt;a href="http://en.wikipedia.org/wiki/Cut%2C_copy_and_paste"&gt;copy &amp;amp; paste&lt;/a&gt;, 或是一些非常詭譎的方式，這邊不多提。&lt;br /&gt;&lt;br /&gt;而在 acts_as_taggable 的最下方，呼叫了：&lt;br /&gt;include ActiveRecord::Acts::Taggable::InstanceMethods&lt;br /&gt;extend ActiveRecord::Acts::Taggable::SingletonMethods&lt;br /&gt;的意思就非常明顯了，將 module InstanceMethods 的 method 變成 MyModel 的 instance method, 將 module SingletonMethods 的 method 變成 MyModel 的 class method.（不太明白為何要取做 SinglethonMethods, 也許只是因為 ClassMethods 用過了吧？）&lt;br /&gt;&lt;br /&gt;原因是 :include 與 :extend 的 message receiver 是 MyModel 而不是 ActiveRecord::Base, 所以被擴充的是 MyModel; ActiveRecord::Base 不受影響。&lt;br /&gt;&lt;br /&gt;大抵上就是這樣了。&lt;br /&gt;&lt;br /&gt;abstract:&lt;br /&gt;init.rb 在 Rails load up 後會執行&lt;br /&gt;install.rb 在 plugin install 後會執行&lt;br /&gt;lib/ 自動加入 load path&lt;br /&gt;&lt;br /&gt;下次再研究 rake 要怎麼用，相信以之拿來做 test 會很方便。&lt;br /&gt;&lt;br /&gt;2007.05.05 godfat 真常&lt;br /&gt;&lt;br /&gt;&lt;b&gt;延伸閱讀&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://wiki.rubyonrails.org/rails/pages/Plugins" target="_blank"&gt;Ruby on Rails Plugin&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8466282272082662343?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/8466282272082662343/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=8466282272082662343' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8466282272082662343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8466282272082662343'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/scriptplugin.html' title='script/plugin'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-5199221150491574369</id><published>2007-05-04T23:34:00.000+08:00</published><updated>2007-05-05T00:01:45.894+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='beast'/><title type='text'>Beast 中文化成功</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_8vS0KjIsbko/RjtV1WklRlI/AAAAAAAAAGk/uJr_i5f_kO8/s1600-h/%E6%93%B7%E5%9C%96_1.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 221px; height: 187px;" src="http://bp3.blogger.com/_8vS0KjIsbko/RjtV1WklRlI/AAAAAAAAAGk/uJr_i5f_kO8/s320/%E6%93%B7%E5%9C%96_1.png" alt="" id="BLOGGER_PHOTO_ID_5060732981361329746" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;介紹完&lt;a href="http://lightyror.thegiive.net/2007/04/beast-lighty.html"&gt;怎麼安裝 Beast&lt;/a&gt; ，我們廢話不多說，直接進入 Beast 中文化。Beast 的 I18N 是採用 GETTEXT 來做的，意思就是只要寫一個 po 檔即可處理大部份的中文化東西。不過還是有很多小地方沒有中文化，依舊需要一一  check。右圖就是成品，這裡就是&lt;a href="http://arbor.ee.ntu.edu.tw/%7Ewisely/download/beast_tw.po"&gt; po檔下載點&lt;/a&gt;。實做方式以及po檔均參考 JavaEye 的 Suninny 先生撰寫的 &lt;a href="http://www.javaeye.com/topic/65034"&gt;[分享]Beast中文Gettext PO档&lt;/a&gt;，感謝他的付出。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;中文化方式如下&lt;br /&gt;&lt;ol&gt;&lt;li&gt;採用之前&lt;a href="http://lightyror.thegiive.net/2007/04/beast-lighty.html"&gt;說好的方式&lt;/a&gt;安裝 beast。&lt;/li&gt;&lt;li&gt;安裝 GETTEXT GEM&lt;br /&gt;gem i gettext&lt;/li&gt;&lt;li&gt;撰寫轉換rake file，新增一個檔案叫做 lib/tasks/gettext.rake，內容是&lt;br /&gt;&lt;pre&gt;desc &lt;span style="color: rgb(0, 128, 0);"&gt;"Create mo-files for L10n"&lt;/span&gt;&lt;br /&gt;task &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;makemo &lt;strong&gt;do&lt;/strong&gt;&lt;br /&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;require&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'gettext/utils'&lt;/span&gt;&lt;br /&gt;GetText.create_mofiles&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;true&lt;/strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"po"&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"locale"&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;新增一個資料夾 po/zh_tw/ ，將這個&lt;a href="http://arbor.ee.ntu.edu.tw/%7Ewisely/download/beast_tw.po"&gt;po檔&lt;/a&gt;放入這個資料夾裡面&lt;/li&gt;&lt;li&gt;產生相對應的 mo 檔，請打入&lt;br /&gt;rake makemo&lt;/li&gt;&lt;li&gt;config/enviroment.rb 裡面，下面這一段 gettext 的部份要註解起來，我也不確定為什麼，反正會產生 error&lt;br /&gt;&lt;pre&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br /&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;require&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'gettext/rails'&lt;/span&gt;&lt;br /&gt;GetText.locale &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"zh"&lt;/span&gt; &lt;span style="color: rgb(68, 68, 68);"&gt;# Change this to your preference language&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;puts&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"GetText found!"&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;rescue&lt;/strong&gt; MissingSourceFile&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; LoadError&lt;br /&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;puts&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;"GetText not found.  Using English."&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;class&lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt; ActionView&lt;/strong&gt;&lt;/span&gt;&lt;/strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;::&lt;/span&gt;Base&lt;br /&gt;  &lt;strong&gt;def&lt;span style="color: rgb(255, 0, 0);"&gt; _&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;(&lt;/span&gt;s&lt;span style="color: rgb(68, 68, 255);"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;    s&lt;br /&gt;  &lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;app/controllers/application.rb 部份加上&lt;br /&gt;&lt;pre&gt;&lt;strong&gt;class&lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt; ApplicationController&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;&lt;strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;&lt;/span&gt; ActionController&lt;/strong&gt;&lt;/span&gt;&lt;/strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;::&lt;/span&gt;Base&lt;br /&gt;&lt;span style="color: rgb(68, 68, 68);"&gt;#init_gettext "beast" if Object.const_defined?(:GetText)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;require&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'gettext/rails'&lt;/span&gt;&lt;br /&gt;init_gettext &lt;span style="color: rgb(0, 128, 0);"&gt;"beast"&lt;/span&gt; &lt;strong&gt;if&lt;/strong&gt; Object.const_defined?&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;GetText&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;GetText.locale &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'zh_tw'&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/pre&gt;&lt;br /&gt;裡面 zh_tw 就是你指定的語系&lt;br /&gt;&lt;/li&gt;&lt;li&gt;重起 server 即可&lt;/li&gt;&lt;/ol&gt;如此就沒問題了。Beast I18N 做的不錯，唯一缺點就是 doc  太少，花了點時間才找到相關資料。&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-5199221150491574369?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/5199221150491574369/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=5199221150491574369' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/5199221150491574369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/5199221150491574369'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/beast_04.html' title='Beast 中文化成功'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_8vS0KjIsbko/RjtV1WklRlI/AAAAAAAAAGk/uJr_i5f_kO8/s72-c/%E6%93%B7%E5%9C%96_1.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-3283191000948139596</id><published>2007-05-04T09:16:00.000+08:00</published><updated>2007-05-04T09:33:32.964+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ria'/><title type='text'>RIA on Rails ?</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.rubyinside.com/wp-content/uploads/2007/05/silverlight.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 219px; height: 92px;" src="http://www.rubyinside.com/wp-content/uploads/2007/05/silverlight.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;M$ 最近推出了 Silverlight 計畫，是一種類似 flash 的 Browser  Plugin，目的也是為了搶供 Flash 的 Multimedia 龍頭位置。雖然只支援 Win + MAC 讓人嚴重懷疑他的接受度，畢竟 Flash 對 Linux 支援度算是很好了。當然他的成敗不是我們所 care 的東西，我們 care 的是 Ruby on Rails。&lt;br /&gt;&lt;br /&gt;根據 &lt;a href="http://www.rubyinside.com/silverlight-and-ruby-on-the-net-clr-473.html"&gt;Ruby Inside 說法&lt;/a&gt;，M$ 在 Silverlight 裡面放了 CLR 的 subset，而且 silverlight 的 CLR 也支援 Ruby。&lt;br /&gt;&lt;blockquote&gt; Microsoft has officially announced C#, Javascript, VB, Python and Ruby support for Silverlight's CLR.&lt;br /&gt;&lt;/blockquote&gt;總之，那一天，或許我們可以在 Sliverlight 上面寫 Ruby 也說不定。這算 Ruby 的一種 RIA Solution嗎 :p 不管如何對 Ruby 都是好事，靜觀其變吧。&lt;br /&gt;&lt;br /&gt;另外值得一提，Flex on Rails 好像越來越成熟了，我也是今天才發現這個網站 &lt;a href="http://flexonrails.net/"&gt;http://flexonrails.net/ &lt;/a&gt;，裡面的東西還蠻多的。教導的都是 Rails 如何跟 Flex 做一個緊密的結合。應該又是另外一個 Ruby RIA Solution吧。&lt;br /&gt;&lt;br /&gt;不過老實說，我對 RIA 以及 Flash 這方面的東西，真的很不熟，所以我講話還是小聲點比較好 :p&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-3283191000948139596?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/3283191000948139596/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=3283191000948139596' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3283191000948139596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/3283191000948139596'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/ria-on-rails.html' title='RIA on Rails ?'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-6007007141737169181</id><published>2007-05-03T00:30:00.000+08:00</published><updated>2007-05-03T09:14:26.251+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gem'/><title type='text'>簡單的建立自己的 Gem Package</title><content type='html'>一不小心就跟  &lt;a href="http://lightyror.thegiive.net/2007/05/require-rubygems.html"&gt;Godfat 寫的議題&lt;/a&gt;衝突，不過沒關係，我是走輕鬆簡單取向的。這次要講的就是如何將自己寫的程式包成 Ruby GEM，本文的參考自 JavaEye 上面的&lt;a href="http://www.javaeye.com/topic/70348" title="固定链接：创建自己的ruby Gems"&gt;创建自己的ruby Gems&lt;/a&gt;，程式也是來自&lt;a href="http://lightyror.thegiive.net/2006/10/plugin.html"&gt;計算民國跟學年度的 Plugin&lt;/a&gt;的範例。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;結構&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;要建立一個 GEM Package，首先要先搞清楚結構。因為我們是走極簡路線的，所以現在一開始連 unit-test 都不要 test。將你的 GEM Package 設定為下面的結構。&lt;br /&gt;&lt;br /&gt;-----gem.spec&lt;br /&gt;|&lt;br /&gt;--README&lt;br /&gt;|&lt;br /&gt;--lib/&lt;br /&gt;&lt;br /&gt;裡面 lib 就是放所有程式的所在。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;結構檔&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;根目錄下面有 gem.spec，跟 README 兩個檔案。其中 gem.spec 是描述 GEM Package 的結構檔，也是最重要的檔案，裡面記載了這個 GEM Package 絕大多數的資訊。可以說學會了寫這個檔案，就學會了打包 GEM Package。這裡要講的是其實 gem.spec 檔名是我隨便取的，檔名不限定，而且他的格式可以使用 ruby 或是 YAML 語法的，這裡先使用 Ruby 語法。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;require&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'rubygems'&lt;/span&gt;&lt;br /&gt;SPEC&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;Gem&lt;span style="color: rgb(68, 68, 255);"&gt;::&lt;/span&gt;Specification.new &lt;strong&gt;do&lt;/strong&gt; |s|&lt;br /&gt;s.name&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;"Taiwan_Year"&lt;/span&gt;&lt;br /&gt;s.version&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;'0.01'&lt;/span&gt;&lt;br /&gt;s.author&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;'thegiive'&lt;/span&gt;&lt;br /&gt;s.email&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;"thegiive at gmail dot com"&lt;/span&gt;&lt;br /&gt;s.homepage&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;"http://lightyror.thegiive.net/"&lt;/span&gt;&lt;br /&gt;s.platform&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;Gem&lt;span style="color: rgb(68, 68, 255);"&gt;::&lt;/span&gt;Platform&lt;span style="color: rgb(68, 68, 255);"&gt;::&lt;/span&gt;RUBY&lt;br /&gt;s.summary&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;"為台灣學年度跟民國所寫的Plugin"&lt;/span&gt;&lt;br /&gt;condidates &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;Dir.glob&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;"{bin,lib,docs,test}/**/*"&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;s.files&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;condidates.delete_if &lt;strong&gt;do&lt;/strong&gt; |item|&lt;br /&gt; item.include?&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;"CVS"&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;|| item.include?&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;"rdoc"&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;s.require_path&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;"lib"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(68, 68, 68);"&gt;    &lt;/span&gt;s.has_rdoc&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;&lt;strong&gt;false&lt;/strong&gt;&lt;br /&gt;s.extra_rdoc_files&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;"README"&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/pre&gt;裡面&lt;br /&gt;&lt;ol&gt;&lt;li&gt;s.name 就是這個 gem 的名稱，也是他打包出來的檔名，也就是說這個 gem package 會叫做 Taiwan_Year-0.01.gem。&lt;/li&gt;&lt;li&gt;s.version 部分 &lt;a href="http://lightyror.thegiive.net/2007/05/require-rubygems.html"&gt;godfat 有解釋過&lt;/a&gt;，盡量從 0.0.1 而不是從 0.0.0 開始寫起。&lt;/li&gt;&lt;li&gt;s.summary 就是當你打入 gem list 出現的簡單文字，安裝了本 gem ，按下 gem list 這裡會出現&lt;br /&gt;&lt;blockquote&gt;sources (0.0.1)&lt;br /&gt;This package provides download sources for remote gem installation&lt;br /&gt;&lt;br /&gt;Taiwan_Year (0.01)&lt;br /&gt;為台灣的學年度跟民國寫的 Plugin&lt;br /&gt;&lt;br /&gt;vim-ruby (2006.07.11)&lt;br /&gt;Ruby configuration files for Vim.  Run 'vim-ruby-install.rb' to&lt;br /&gt;complete installation.&lt;/blockquote&gt;這樣的情況。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;再來就是 README ，就是打入一些information進去摟。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;放入程式&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;最後把程式放入到 lib 底下，這裡是使用&lt;a href="http://lightyror.thegiive.net/2006/10/plugin.html"&gt;計算民國跟學年度的 Plugin&lt;/a&gt;的範例，把他放入 lib/year.rb 檔案裡面&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:100%;"&gt;&lt;strong&gt;class&lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt; Time&lt;/strong&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 68);font-size:100%;" &gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;strong&gt;def&lt;span style="color: rgb(255, 0, 0);"&gt; roc_year&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;self&lt;/strong&gt;.year - &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);font-size:100%;" &gt;1911&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;def&lt;span style="color: rgb(255, 0, 0);"&gt; student_year&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;if&lt;/strong&gt; &lt;strong&gt;self&lt;/strong&gt;.month &lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);font-size:100%;" &gt;&lt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt; &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);font-size:100%;" &gt;7&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;strong&gt;self&lt;/strong&gt;.roc_year - &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);font-size:100%;" &gt;1&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;strong&gt;else&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;self&lt;/strong&gt;.roc_year&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;打包 gem &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;當程式都放好後，開始打包 gem 了。我們這裡使用 gem build 指令來打包&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span&gt;&lt;span&gt;gem build gem.spec  &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;這裡面的 gem.spec 就是你剛剛寫的結構檔的檔名。成功了之後，你就會發現我們已經產生了一個 Taiwan_Year-0.01.gem。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;安裝 gem &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;要安裝這個剛打包好的 gem 就是直接打&lt;br /&gt;&lt;blockquote&gt;gem i TaiwanYear-0.01.gem&lt;br /&gt;&lt;/blockquote&gt;即可。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;使用 gem &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;要使用剛剛安裝好的 gem package ，首先要 require 'rubygems' ，告訴程式這個是使用 gem 的程式。&lt;br /&gt;&lt;br /&gt;其次要搞清楚程式檔名，像我雖然 GEM Package 叫做 TaiwanYear ，但是我的程式其實是放在 lib/year.rb 底下的，所以使用上還是得必須  require 'year' 。&lt;br /&gt;&lt;br /&gt;解決方式很簡單，當我們放入程式到 lib 裡面的時候，請將程式名稱取的跟 GEM Package 名字相同即可。像是當初在打包時，我們就將程式放在  lib/TaiwanYear.rb 底下，以後使用上就可以這樣使用。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;require&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'rubygems'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;require&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'TaiwanYear'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;puts&lt;/strong&gt;&lt;/span&gt; Time.now.roc_year&lt;/pre&gt;如此，我們已經學會如何打包 gem 了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6007007141737169181?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/6007007141737169181/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=6007007141737169181' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6007007141737169181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6007007141737169181'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/gem-package.html' title='簡單的建立自己的 Gem Package'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-2930035907585192483</id><published>2007-05-02T02:46:00.000+08:00</published><updated>2007-05-02T02:55:12.155+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='gem'/><title type='text'>require 'rubygems'</title><content type='html'>寫到一半因為有其他事所以先放著，結果回來就是八小時後了…。&lt;br /&gt;有夠累。&lt;br /&gt;&lt;br /&gt;==&lt;br /&gt;&lt;br /&gt;大致調查（survey?）了一下要怎麼樣把程式 package 成 rubygem, 主要參考書籍當然是 Programming Ruby 2nd, 這本我看好久還是沒看完的書。（還不都是因為他太厚了…）在 Creating Your Own Gems 這一節中，相當詳細地描述了如何打包（在 MtG 中，不知為何把 entwine 翻譯成打包，瞬間從 spell 的意味變成像外帶一樣）。這邊將簡單示範一次我如何發佈 ludy 的。&lt;br /&gt;&lt;br /&gt;首先呢，rubygems 有建議的檔案配置（layout），可以不依照這個規則來做，但一般來說建議使用跟別人相同的方式。所有雜七雜八的東西放在根目錄下，例如 ludy-0.0.1 裡面放的有：ludy.gemspec, LICENSE, NOTICE, README. 其他目錄則是很常見的：bin, doc, lib, test. 我沒有 bin 也沒有 doc, 所以只有放 lib 和 test 兩個目錄。&lt;br /&gt;&lt;br /&gt;顧名思義，lib 裡面放的就是 ludy 本身的 source code, 專門拿來給人 require 用。而 test 底下則是所有的 test program, 以 tc_ 開頭的是 TestCase, 可以單獨執行，但主要是由 ts_ 開頭的 TestSuite 去 require 起來，然後 ts_ 會自動執行這些 tc_.&lt;br /&gt;&lt;br /&gt;所以我的 ts_ludy.rb 裡面只有兩行：&lt;br /&gt;&lt;br /&gt;require(File.join(File.dirname(__FILE__), '..', 'lib', 'ludy'))&lt;br /&gt;require_all_in_dir __FILE__&lt;br /&gt;&lt;br /&gt;第一行是把 lib/ludy.rb require 進來，這是使用 ludy 部份元件的必要手續。這樣做的理由是有些 path 問題很煩，所以我把處理 path 的 func 寫在 ludy.rb 中，如此一來需要確保路徑的只有 ludy.rb 這一個檔案。至於為何這裡要使用相對路徑去 require 呢？因為我堅持兩種使用 ludy 的方式，一個是安裝成 gem, 另一個是直接丟到 project 目錄下，使用路徑去 require. 前者不用說，可以有一個很標準的方式使用，但後者就不一定了。&lt;br /&gt;&lt;br /&gt;為了處理這個問題，ludy 內部需要某些其他 ludy tool 時，就改用 require_ludy, 集中處理 require 問題，避免重複把相同路徑加入 load path. 使用者當然也可以使用 require_ludy, 或是依然習慣使用 require, 那麼只要確定自己 require 的 path 是正確的就好了，ludy 內部不會有路徑問題。至於 gem version, require 的方式就很單純用 require 'ludy/tool_name' 或是 require_ludy 'tool_name' 就好了。&lt;br /&gt;&lt;br /&gt;第二行，則是把所有 tc_ 開頭的 TestCase require 進 TestSuite 裡面，（其實是同個目錄下所有的 .rb 檔，只是現在 test/ 下只有 tc_ 和正在執行的 ts_ 而已）unit test 就會自動執行了。不過這個 require_all_in_dir 的第一個參數卻是檔案名稱，名字好像取得不太好的樣子。&lt;br /&gt;&lt;br /&gt;ok, 也就是說我要打包的東西是 ludy.gemspec, LICENSE, NOTICE, README, lib/*.rb, test/*.rb. 其中 lib/ 底下還有其他資料夾，也要一併打包。那麼寫好的 gemspec 就是&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;require 'rubygems'&lt;br /&gt;&lt;br /&gt;spec = Gem::Specification.new{|s|&lt;br /&gt;  s.name     = 'ludy'&lt;br /&gt;  s.version  = '0.0.1'&lt;br /&gt;  s.author   = 'Lin Jen-Shin(a.k.a. godfat)'&lt;br /&gt;  s.email    = 'strip number: 135godfat7911@246gmail.890com'&lt;br /&gt;  s.homepage = '&lt;a href="http://ludy.rubyforge.org/" target="_blank"&gt;http://ludy.rubyforge.org/&lt;/a&gt;'&lt;br /&gt;  s.platform = Gem::Platform::RUBY&lt;br /&gt;  s.summary  = 'Aims to extend Ruby standard library, providing some useful&lt;br /&gt;                tools that\'s not existed in the standard library.'&lt;br /&gt;  candidates = Dir.glob '{bin,doc,lib,test}/**/*'&lt;br /&gt;  candidates+= Dir.glob '*'&lt;br /&gt;  s.files    = candidates.delete_if{|item|&lt;br /&gt;                 item.include?('CVS') || item.include?('rdoc') ||&lt;br /&gt;                 File.extname(item) == '.gem'&lt;br /&gt;               }&lt;br /&gt;&lt;br /&gt;  s.require_path = 'lib'&lt;br /&gt;  s.autorequire  = 'ludy'&lt;br /&gt;  s.test_file    = 'test/ts_ludy.rb'&lt;br /&gt;  s.has_rdoc     = false&lt;br /&gt;  # s.extra_rdoc_files = []&lt;br /&gt;  # s.add_dependency 'multi', '&gt;=0.1'&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if $0 == __FILE__&lt;br /&gt;  Gem::manage_gems&lt;br /&gt;  Gem::Builder.new(spec).build&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;其中 Dir.glob 的部份我還沒研究，所以寫得很爛，居然用補正的方式。反正就是全部抄自 Programming Ruby 2nd, 再做一點修修改改。其中最下面的 if $0 == __FILE__ 可以判斷這個程式是不是直接被 ruby interpreter 執行？如果是的話，就呼叫建立 rubygem 的 method. 不是的話，就只要定義 spec 就好了。&lt;br /&gt;&lt;br /&gt;前者就是：&lt;br /&gt;ruby ludy.gemspec&lt;br /&gt;或是如果有加 #! 的話：&lt;br /&gt;./ludy.gemspec&lt;br /&gt;如果 ludy.gemspec 在現在目錄下的話。&lt;br /&gt;&lt;br /&gt;後者就是：&lt;br /&gt;gem build ludy.gemspec&lt;br /&gt;&lt;br /&gt;這兩種方式都可以產生 ludy-0.0.1.gem. 接著再下：&lt;br /&gt;gem install ludy&lt;br /&gt;就可以正確安裝 ludy gem 了。至於 remote 的部份呢？只要上傳到 rubyforge 的 file release system 上，rubyforge 每日會有數次掃描裡面的 *.gem, 自動放到 rubygems 的 repository. 這件事我已經做完了，所以現在可以直接：&lt;br /&gt;&lt;br /&gt;gem install ludy&lt;br /&gt;&lt;br /&gt;就能看到我寫的一點程式了 :)&lt;br /&gt;不過其實我只是在測試功能而已，本來是想標版本號 0.0.0, 可惜這樣用：&lt;br /&gt;&lt;br /&gt;gem uninstall ludy&lt;br /&gt;&lt;br /&gt;時會出一點問題。所以就還是標成 0.0.1, 但未來的更新暫時都不改版本號。正式釋出時大概會是 0.0.2 吧 :p 還是歡迎大家抓回去試試，使用方法全在 unit test 裡面，文件懶得寫了。&lt;br /&gt;&lt;br /&gt;homepage:&lt;br /&gt;&lt;a href="http://ludy.rubyforge.org/" target="_blank"&gt;http://ludy.rubyforge.org/&lt;/a&gt;&lt;br /&gt;有空時會弄個應有的版面出來。&lt;br /&gt;&lt;br /&gt;2007.05.02 godfat 真常&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-2930035907585192483?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/2930035907585192483/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=2930035907585192483' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2930035907585192483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/2930035907585192483'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/05/require-rubygems.html' title='require &apos;rubygems&apos;'/><author><name>Lin Jen-Shin (godfat)</name><uri>http://www.blogger.com/profile/04471393622959484230</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://photos1.blogger.com/x/blogger2/1504/489948791395950/1600/z/711327/gse_multipart5683.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-4701474018275987386</id><published>2007-04-30T22:27:00.000+08:00</published><updated>2007-05-01T10:09:05.084+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='beast'/><title type='text'>Beast ：最符合 Lighty 想法的討論區</title><content type='html'>當我一開始看到 &lt;a href="http://beast.caboo.se/"&gt;Beast &lt;/a&gt;的時候，我總覺得這是一個奇怪的東西， Beast 只是一個簡單到不能再簡單的「討論區」，而且真的沒別的了。可是當我開始真正花時間在 survey 他的時候，我發現到這真的是一個把精簡 code 的精神發揮到極限的東西，裡面的 code 相當的精彩。&lt;br /&gt;&lt;br /&gt;我們來看看他的內容，截至目前的 trunk 為止，Controller 504行，Helper 94行，Model 238 行，Library 69行，如果不算 Unit test 一共 905行。一千行以下的討論區，到底能有什麼功能呢？&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;簡單易用的討論區&lt;/span&gt;：因為他就是討論區，所以一切的功能就是討論區，不過使用起來感覺蠻好用的。也支援一些文字格式化。&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;REST Web API&lt;/span&gt;：他是目前 REST 化最徹底的 Rails 套件之一，也延續了 Rails 1.2 REST 最棒的特色，「當你完成一個內部功能的同時，你也順便寫完了 REST Web API」。&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;OpenID Support&lt;/span&gt;：ㄜ，你沒看錯，他有 Open ID Support 。&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;GetTEXT Support&lt;/span&gt;：所以 i18n 解決了。Btw，在我讀 Beast code 的同時，我也差不多把 po 檔寫完了，明後天就可以 release 出來。&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;沒有做任何縮圖上傳的機制&lt;/span&gt;：沒錯，你沒看錯。 Beast 是直接使用 gravatar 的縮圖，所以如果你沒有 gravatar 的帳號，就註冊一個吧。這樣的作法雖然奇怪，但是相當的合乎 MarshUP 的想法&lt;/li&gt;&lt;/ol&gt;仔細觀察 Beast 的設計哲學，可以說是「討論區該有的功能，Beast 一行都不少，除了最重要的功能之外，Beast一行 code 都不多」。不管是自己使用 Beast ，或是看 Beast 裡面的 code ， Beast 都是相當好的選擇。&lt;br /&gt;&lt;br /&gt;介紹了Beast，當然簡單講一下怎麼安裝。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;下載 beast &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;這裡使用 svn 來安裝&lt;br /&gt;&lt;blockquote&gt;svn checkout http://svn.techno-weenie.net/projects/beast/trunk&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;安裝 Edge Rails&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;在剛剛下載下來的svn目錄下，打入&lt;br /&gt;&lt;blockquote&gt;rake freeze_edge&lt;/blockquote&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;安裝 RedCloth&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;gem install RedCloth&lt;/blockquote&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;修改 config&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;修改 dayabase.yml 的 production 設定&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;將 db schema 設定到 db 裡面&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;rake db:schema:load RAILS_ENV=production&lt;/blockquote&gt;如此，啟動您的 Rails App 即可。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4701474018275987386?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/4701474018275987386/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=4701474018275987386' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4701474018275987386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4701474018275987386'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/04/beast-lighty.html' title='Beast ：最符合 Lighty 想法的討論區'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-6529958089469170460</id><published>2007-04-28T14:02:00.000+08:00</published><updated>2007-04-28T20:35:45.040+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cache'/><title type='text'>Rails Cache 效率上的問題</title><content type='html'>Fragement Cache 是大家常用的Rails 內建 Cache 機制，不過昨天看到石鍋拌飯先生寫的&lt;a href="http://www.robinlu.com/blog/archives/140"&gt;rails缓存机制的几个问题&lt;/a&gt;，裡面提到一些 Fragement Cache 的問題，這裡做一下筆記。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;1. read_fragment 實做方式效率不佳&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;在  &lt;span class="ruby-comment cmt"&gt;actionpack/lib/action_controller/caching.rb 裡面，read_fragment 假設是使用 file_store 的話，實做方式不佳&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;&lt;strong&gt;def&lt;span style="color: rgb(255, 0, 0);"&gt; read&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;(&lt;/span&gt;name, options = nil&lt;span style="color: rgb(68, 68, 255);"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt; &lt;span style="color: rgb(68, 68, 68);"&gt;#:nodoc:&lt;br /&gt;&lt;/span&gt;File.&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;open&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;real_file_path&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;name&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'rb'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; |f| f.read &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt; &lt;strong&gt;rescue&lt;/strong&gt; &lt;strong&gt;nil&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/pre&gt;每次判斷 fragment 都得 open file 一次，的確會損耗效率。解決方式是用 File.exist? 來判斷即可。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;2.  expire_fragment 使用 regular expression&lt;/span&gt; 效率不佳&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;不算問題啦，假設 expire_fragment 使用 regular expression ，根據內建的實做方式，他會一個一個目錄下去用  regular expression ，然後 regular expression 通常執行速度不佳，所以就....&lt;br /&gt;&lt;br /&gt;解決方式有兩個，第一個就是不要在 expire_fragment 使用 regular expression，另外就是使用 backend script 來 expire cache 即可。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;3. expire_cache 的時間點&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;簡單講就是 controller read_fragment 的到 cache ，但是當 render 的時候卻剛剛好被 expire 掉了，就會出現 nil object error 。因為發生機率比較低，解決方式只能說視情況而定。&lt;br /&gt;&lt;br /&gt;當然也可以照著原作者的講法，在 view 當中判斷 Model obj 是不是存在，不過這個作法就比較 dirty。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6529958089469170460?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/6529958089469170460/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=6529958089469170460' title='5 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6529958089469170460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6529958089469170460'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/04/rails-cache.html' title='Rails Cache 效率上的問題'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-5917303973287609658</id><published>2007-04-27T14:27:00.000+08:00</published><updated>2007-04-27T14:59:31.298+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='acts_as_atggable'/><title type='text'>acts_as_taggable Plugin 使用方式</title><content type='html'>Tag 似乎是目前所有Web2.0網站所必備的功能，也有人這樣講「沒有 Tag 就不是 Web 2.0 的網站」。雖然綜觀 Web 2.0 的定義，跟 tag 似乎一點關係都沒有 XD ，不過這完全不要緊，tag 不管是不是 Web 2.0，他對於「歸類」這檔事所帶來的影響是跟「分類」一樣重大的。&lt;br /&gt;&lt;br /&gt;Rails 上面要實踐 tag 功能最簡單的就是使用 acts_as_taggable 來做，說到這個 acts_as_taggable 可能會令人有點 confuse，他分成 &lt;a href="http://wiki.rubyonrails.com/rails/pages/ActsAsTaggablePluginHowto"&gt;Plugin 版本&lt;/a&gt;，跟 &lt;a href="http://wiki.rubyonrails.org/rails/pages/Acts+As+Taggable+Gem"&gt;Gem 版本&lt;/a&gt;的。兩者實做方式不太一樣， Plugin 版本跟 Gem 版本最大的不同呢，就是 Plugin 版本 acts_as_taggable 他是使用兩個 table 就可以表示許多個 Model 的 tag，你不需要使用多個 table 來表示不同 Model 的 Tag ，再這一點來看，的確是一個不錯的設計，而 GEM 版本的 acts_as_taggable 你必須每個 Model 的都新增一個 table 來表示 tag。也因為設計哲學上面的不同，也有&lt;a href="http://jyte.com/cl/there-are-both-acts_as_taggable-plugin-and-acts_as_taggable-gem.-these-are-not-the-same"&gt;投票&lt;/a&gt;來投到底那個比較好。&lt;br /&gt;&lt;br /&gt;我們這裡先介紹 Plugin。要先注意到的，act_as_taggable plugin 是depend on Rails 1.1 以上的，所以你必須使用 Rails 1.1 以上的版本。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;安裝 acts_as_taggable&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;script/plugin install acts_as_taggable&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;建立相關 table &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;script/generate migration add_tag_support&lt;br /&gt;&lt;br /&gt;在 db/migrate/ 檔案裡面這樣寫&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;strong&gt;class&lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt; AddTagSupport&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;&lt;strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;&lt;/span&gt; ActiveRecord&lt;/strong&gt;&lt;/span&gt;&lt;/strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;::&lt;/span&gt;Migration&lt;br /&gt;&lt;strong&gt;def&lt;span style="color: rgb(255, 0, 0);"&gt; self&lt;/span&gt;.up&lt;/strong&gt;&lt;br /&gt;&lt;span style="color: rgb(68, 68, 68);"&gt;#Table for your Tags&lt;br /&gt;&lt;/span&gt;create_table &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;tags &lt;strong&gt;do&lt;/strong&gt; |t|&lt;br /&gt;  t.column &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;name&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;string&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;create_table &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;taggings &lt;strong&gt;do&lt;/strong&gt; |t|&lt;br /&gt;  t.column &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;tag_id&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;integer&lt;br /&gt;  &lt;span style="color: rgb(68, 68, 68);"&gt;#id of tagged object&lt;br /&gt;  &lt;/span&gt;t.column &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;taggable_id&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;integer&lt;br /&gt;  &lt;span style="color: rgb(68, 68, 68);"&gt;#type of object tagged&lt;br /&gt;  &lt;/span&gt;t.column &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;taggable_type&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;string&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(68, 68, 68);"&gt;# Index your tags/taggings&lt;br /&gt;&lt;/span&gt;add_index &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;tags&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;name&lt;br /&gt;add_index &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;taggings&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;tag_id&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;taggable_id&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;taggable_type&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;def&lt;span style="color: rgb(255, 0, 0);"&gt; self&lt;/span&gt;.down&lt;/strong&gt;&lt;br /&gt;drop_table &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;taggings&lt;br /&gt;drop_table &lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;tags&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/pre&gt;然後打入&lt;br /&gt;&lt;br /&gt;rake migrate&lt;br /&gt;&lt;br /&gt;建立相關  table。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;設定 Model &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;設定方式沒有比這個更簡單了，就是在你要下 tag 的 Model 寫入&lt;br /&gt;&lt;pre&gt;&lt;strong&gt;class&lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt; ModelName&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;&lt;strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;&lt;/span&gt; ActiveRecord&lt;/strong&gt;&lt;/span&gt;&lt;/strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;::&lt;/span&gt;Base&lt;br /&gt;acts_as_taggable&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/pre&gt;即可。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;開始使用&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;下 tag &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;如果要對其中一個 Model 物件下 tag ，tag 內容是 'abc def ghi'，代表這是一個字串，每個 tag pattern 用空白隔開。那我們就可以這樣下 tag&lt;br /&gt;&lt;blockquote&gt;obj.tag_with( 'abc def ghi')&lt;/blockquote&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;取出這個 Model 所有的 tag &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;如果，要取出這個 Model 物件下面的 tag，那就&lt;br /&gt;&lt;blockquote&gt;obj.tags &lt;/blockquote&gt;這是一個  tag  的 array ，裡面每個東西都是一個 tag 物件，如果想要取出這個 tag array 的每個 tag name，就這樣用&lt;br /&gt;&lt;blockquote&gt;obj.tags.each { |tag| puts tag.name }&lt;/blockquote&gt;即可。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;尋找同一個 tag 的所有 entry&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;如果要搜尋這個 Model 底下所有下這個 tag  的 entry，就這樣使用&lt;br /&gt;&lt;blockquote&gt;obj.find_tagged_with('abc')&lt;br /&gt;&lt;/blockquote&gt;他會回傳同一個 Model array，裡面是有下這個 tag 的 Model 物件。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;覆蓋掉 tag &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;如果想用新的 tag ，就直接用 tag_with 覆蓋掉即可&lt;br /&gt;&lt;blockquote&gt;obj.tag_with('new tag') &lt;/blockquote&gt;即可&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;刪除其中一個 tag&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;只想刪除掉其中一個 tag ，那就用 ActiveRecord 裡面的 destroy 即可，下面例子就是刪除 tag id 等於 1的 tag ，但是不刪除其他 tag&lt;br /&gt;&lt;blockquote&gt;obj.tags.each do |tag|&lt;br /&gt;tag.destroy if tag.id == 1&lt;br /&gt;end&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;這樣即可。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-5917303973287609658?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/5917303973287609658/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=5917303973287609658' title='5 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/5917303973287609658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/5917303973287609658'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/04/actsastaggable-plugin.html' title='acts_as_taggable Plugin 使用方式'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-7727002835715020259</id><published>2007-04-26T14:13:00.000+08:00</published><updated>2007-04-26T14:29:15.942+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><title type='text'>JRuby 0.9.9 Release</title><content type='html'>好掉詭的版本編號，好像在倒數計時一樣。&lt;a href="http://docs.codehaus.org/display/JRUBY/2007/04/23/JRuby+0.9.9+Released"&gt;JRuby 0.9.9 release&lt;/a&gt;，主要的更新是在修正了很多 bugs ，並且又增加 40% 的 performance。對於 Rails 支援能力也變強了， &lt;a href="http://www.rubyinside.com/jruby-099-released-yes-its-a-big-deal-464.html"&gt;Mephisto 可以在 JRuby 上面跑了&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;The JRuby community is pleased to announce the release of JRuby 0.9.9.&lt;br /&gt;&lt;br /&gt;Homepage: http://www.jruby.org/&lt;br /&gt;Download: http://dist.codehaus.org/jruby/&lt;br /&gt;&lt;br /&gt;This release has largely been a stabilization release where we have spent&lt;br /&gt;more focus on Ruby compatibility.  We are gearing up for a 1.0 release.  Here&lt;br /&gt;are some of the more significant acheivements for 0.9.9:&lt;br /&gt;&lt;br /&gt;Major compatibility and performance overhaul of String, Array, Hash&lt;br /&gt;Many YAML and Marshalling issues have been fixed&lt;br /&gt;Java Integration overhaul fixing many outstanding issues&lt;br /&gt;180 Jira issues resolved&lt;br /&gt;Several more bottlenecks removed&lt;br /&gt;Rails applications like Mephisto and plugins like Goldberg are running without hitches&lt;br /&gt;Performance has improved by 40% over 0.9.8 based on YARV benchmarks&lt;br /&gt;With all the hard work done by Marcin Mielżyński and Bill Dortch we are adding&lt;br /&gt;them as core committers.  Their contributions have made a huge difference in&lt;br /&gt;our progress as of late.&lt;br /&gt;We also want to thank all people who hang out on IRC, triage/report/patch&lt;br /&gt;issues, and communicate on our mailing lists.  Their interest has really&lt;br /&gt;helped shape JRuby into a better implementation.&lt;br /&gt;&lt;br /&gt;Please take JRuby 0.9.9 for a spin and help us root out the last issues&lt;br /&gt;before our 1.0 release!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7727002835715020259?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/7727002835715020259/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=7727002835715020259' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7727002835715020259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/7727002835715020259'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/04/jruby-099-release.html' title='JRuby 0.9.9 Release'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-6561736296409362984</id><published>2007-04-24T09:07:00.000+08:00</published><updated>2007-04-24T09:22:04.191+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='http'/><title type='text'>Net::HTTP 使用方式</title><content type='html'>在 UbiSunrsie 裡面介紹過的小小 Script 裡面有用到，就直接用範例來解釋一下使用方式。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;GET&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;require&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'net/http'&lt;/span&gt;&lt;br /&gt;Net&lt;span style="color: rgb(68, 68, 255);"&gt;::&lt;/span&gt;HTTP.version_&lt;span style="color: rgb(255, 0, 0);"&gt;1&lt;/span&gt;_&lt;span style="color: rgb(255, 0, 0);"&gt;2&lt;/span&gt;&lt;br /&gt;Net&lt;span style="color: rgb(68, 68, 255);"&gt;::&lt;/span&gt;HTTP.start&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;'www.google.com.tw'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;80&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;|http|&lt;br /&gt;  response &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; http.get&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;'/index.html'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;puts&lt;/strong&gt;&lt;/span&gt; response.body&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;/pre&gt;基本上，Start一個 Net::HTTP Connection HOST，然後使用 http.get來抓取你要的頁面，最後用 response.body 印出來即可。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;POST&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;require&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'net/http'&lt;/span&gt;&lt;br /&gt;Net&lt;span style="color: rgb(68, 68, 255);"&gt;::&lt;/span&gt;HTTP.version_&lt;span style="color: rgb(255, 0, 0);"&gt;1&lt;/span&gt;_&lt;span style="color: rgb(255, 0, 0);"&gt;2&lt;/span&gt;&lt;br /&gt;url &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;'example.com'&lt;/span&gt;&lt;br /&gt;action &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'/cgi-bin/query'&lt;/span&gt;&lt;br /&gt;Net&lt;span style="color: rgb(68, 68, 255);"&gt;::&lt;/span&gt;HTTP.start&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt; url &lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;80&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;|http|&lt;br /&gt;  response &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; http.post&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt; action &lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt;  &lt;span style="color: rgb(0, 128, 0);"&gt;'var1=value1&amp;var2=value2'&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;  response.body.each &lt;strong&gt;do&lt;/strong&gt; |line|&lt;br /&gt;    &lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;puts&lt;/strong&gt;&lt;/span&gt; line&lt;br /&gt;  &lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;/pre&gt;稍微複雜一點的作法，除了 http.get 變成 http.post 之外，後面的 variable = value 的形式是採用 application/x-www-form-urlencoded 的形式傳遞出去的，大家應該都很熟悉。&lt;br /&gt;&lt;br /&gt;如果不喜歡這樣，還有其他作法&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;require&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'net/http'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;require&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'uri'&lt;/span&gt;&lt;br /&gt;res &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; Net&lt;span style="color: rgb(68, 68, 255);"&gt;::&lt;/span&gt;HTTP.post_form&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;URI.parse&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;'http://example.com'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;'var'&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'value'&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'var2'&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;=&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;'value2'&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;  res.body.each &lt;strong&gt;do&lt;/strong&gt; |line|&lt;br /&gt;     &lt;span style="color: rgb(165, 42, 42);"&gt;&lt;strong&gt;puts&lt;/strong&gt;&lt;/span&gt; line&lt;br /&gt;  &lt;strong&gt;end&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/pre&gt;好處是 value 傳遞是用 hash 方式來傳遞，比較 Ruby 化，壞處是比起&lt;span style="font-family:monospace;"&gt; &lt;/span&gt;Net&lt;span style="color: rgb(68, 68, 255);"&gt;::&lt;/span&gt;HTTP.post_form ，我比較喜歡 http.post 這樣的形式。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6561736296409362984?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/6561736296409362984/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=6561736296409362984' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6561736296409362984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/6561736296409362984'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/04/nethttp.html' title='Net::HTTP 使用方式'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-22416220904508357</id><published>2007-04-22T21:50:00.000+08:00</published><updated>2007-04-26T15:55:04.354+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='talk'/><title type='text'>Ruby on Rails in UbiSurise 圓滿結束</title><content type='html'>感謝各位的支持，這次的 talk 在沒有人踢館，講的笑話都大家都捧場的情況下結束。兩個禮拜連續講兩場實在太累了，Blog更新也有點怠慢，先說聲抱歉。關於這次的 Demo 程式，我會整理一下看看要用啥方式 Release，而投影片&lt;!--a href="http://arbor.ee.ntu.edu.tw/%7Ewisely/download/UbiSunrise.pdf"&gt;下載在此&lt;/a--&gt;在下面。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;object type="application/x-shockwave-flash" data="https://s3.amazonaws.com:443/slideshare/ssplayer.swf?id=42525&amp;doc=ruby-on-rails-in-ubisunrise-13180" width="425" height="348"&gt;&lt;param name="movie" value="https://s3.amazonaws.com:443/slideshare/ssplayer.swf?id=42525&amp;doc=ruby-on-rails-in-ubisunrise-13180" /&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-22416220904508357?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/22416220904508357/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=22416220904508357' title='5 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/22416220904508357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/22416220904508357'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/04/ruby-on-rails-in-ubisurise.html' title='Ruby on Rails in UbiSurise 圓滿結束'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-4622134434508933345</id><published>2007-04-18T20:08:00.000+08:00</published><updated>2007-04-18T17:59:44.283+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rest'/><title type='text'>REST 簡介</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;前言&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;寫這篇是因為我在 &lt;a href="http://lightyror.blogspot.com/2006/12/blog-post.html"&gt;滿紙荒唐言，一把心酸淚&lt;/a&gt; 裡面有講到&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;blockquote&gt;我連REST 的好處都不甚了解，就大張旗鼓的吹 REST 的好？&lt;/blockquote&gt;所以我開始努力 survey REST 的東西，終於在 &lt;a href="http://osdc.tw/"&gt;OSDC &lt;/a&gt;主講 T&lt;/span&gt;he furture of RoR - The new features in RoR 2.0。原本以為自己已經徹底瞭解 REST，但是隨著時間的逼近，我越來越發現「我不知道 REST 真正的好處」。最後，當我在 OSDC 講完之後，大家就七嘴八舌給我一些意見，越討論越發現我真是個笨蛋&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;在 OSDC 這種場合，我才是學生，場下聽的強者們才是我的老師&lt;/span&gt;。&lt;/blockquote&gt;現在的我，有了大家的加持後，反而越來越有自信了點，我終於允許我在 Blog 寫有關於 REST 的文章。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;REST is about Resource&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;在講 REST 之前，我們來看看Resource 。當你了解 Resource，那麼你就了解了 REST。我們來看看 &lt;a href="http://en.wikipedia.org/wiki/Image:Resttriangle.svg"&gt;Wikipedia 這張圖&lt;/a&gt;，這個三角形是在講解 Resource 最重要的三個東西，Nouns，Verb，Type。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/en/thumb/8/89/Resttriangle.svg/273px-Resttriangle.svg.png"&gt;&lt;img dragover="true" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 267px; height: 149px;" src="http://upload.wikimedia.org/wikipedia/en/thumb/8/89/Resttriangle.svg/273px-Resttriangle.svg.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Nouns&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;在網路上，每個URL帶給我們的意義其實就是代表各式各樣的資源（&lt;span style="font-weight: bold;"&gt;Resource&lt;/span&gt;），有些可能代表你的個人日誌，有些代表我出去玩的圖片，有些代表你最喜歡的歌手的音樂，有些代表你朋友搞笑的影片。Resource 裡面，Nouns 其實是一個 URL，他代表網路上面 Resource 的唯一的位址，同一個 resource 理論上來說，應該只有一個 URL 代表這個 Resource。用超過一個 URL 來代表同一個 Resource 是不夠漂亮的方式。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Type&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;而 Type 是什麼呢？我們剛剛講 URL 代表Resource 的位址。但是 Resource 其實跟大家想的有點不太一樣，resource 不是只代表一個檔案，他是代表一個概念。舉個例子，這張圖片&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.thegiive.net/image.png/image-full.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 223px; height: 32px;" src="http://www.thegiive.net/image.png/image-full.jpg" alt="" border="0" /&gt;&lt;/a&gt;是 一張PNG圖片，裡面是我的 Email 。他的位置是在 http://www.thegiive.net-a.googlepages.com/image.png，但是如果我今天將這個 PNG 轉檔成為 JPG，他的位置就變成了 http://www.thegiive.net-a.googlepages.com/image.&lt;span style="color: rgb(255, 0, 0);"&gt;jpg&lt;/span&gt;。雖然兩者的 URL 不相同，但是對我們來說，PNG 跟 JPG 這兩張圖其實代表的意義是相同的，裡面的圖案就是我的 Email。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;所以，儘管 Format 不同，他們依舊是同一個 Resource，而這些 Format 就是 Type&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;好， 這些東西大家應該都可以了解吧。我們問些奇怪的問題，假設今天有一個 XML file http://www.thegiive.net- a.googlepages.com/image.&lt;span style="color: rgb(255, 0, 0);"&gt;xml&lt;/span&gt;  這個XML檔案裡面記載著我的 Email 帳號&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;&lt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;xml&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;&lt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;email&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;thegiive at gmail dot com&lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;&lt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;/email&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;&lt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;/xml&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/pre&gt;那麼這個 XML File 跟上面的圖，算是同一個 Resource 嗎？是的，雖然 XML 跟 JPG ，PNG 是完全不同的東西，但是他們都記載同樣的意義，那個意義就是我的 Email 帳號，也就是他們代表同一個 resource。&lt;br /&gt;&lt;br /&gt;如果你能夠接受不同格式的檔案其實代表同一個 Resource 的想法，那麼今天這個網址&lt;br /&gt;&lt;blockquote&gt;http://abc.com/blog/1&lt;/blockquote&gt; 如 果以 HTML Format 來說，他可能是一個可以顯示在 Browser 上面的 HTML ，裡面記載這個 Blog 的內容。但是如果是 XML Format，他可能是一個記載這個 Blog 作者是誰的XML 。如果是以 RSS Format 來看，他可能是這個 Blog 的最新文章。但是儘管 Format 不同，內容不同，但是他們還是代表同一個 resource ，也就是這個 Blog。&lt;br /&gt;&lt;br /&gt;&lt;span&gt;在 Web 上面，Resource 是一個概念，而不僅僅是一個檔案。一個 resource 可能有各種不同的 Content Type，但是依舊代表同一個 resource。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Verbs&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;至於三角形的最後一角Verbs ，就是操作 Resource 的方式。我們該如何操作網路上各式各樣的資源呢？&lt;br /&gt;&lt;br /&gt;Web 用宏觀來說，其實就是一個超級大的資料庫，裡面有各式各樣不同的 resource，每個 URL 都是指向各種不同的 Resource，我們每天上網，其實都是藉由 HTTP 來 request 各式各樣不同的 Resource。&lt;br /&gt;&lt;br /&gt;既然 Web 根本就是一個網路上面 Resource 的資料庫，每個 Resource 都是跟資料庫裡面的 Data Entry 類似。那麼有用過資料庫的人都知道，我們每天對資料庫的每個 Data Entry 做四個動作，也就是經典的 CRUD（Create，Read，Update，Delete）。盡管 SQL 指令再多，其實我們對資料庫的操作，都超不出 CRUD 這四個動作。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;那們，我們對 Web 上面的 resource，有沒有相對應的 CRUD 呢？&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ietf.org/rfc/rfc2616.txt"&gt;RFC 2616 &lt;/a&gt;裡面講到， HTTP 1.1 一共有八個 method（我在演講中提到只有四個 Method，是錯誤的，謝謝聽眾指正。），裡面有兩個 Method 是大家不可能不懂的&lt;br /&gt;&lt;ul&gt;&lt;li&gt;GET&lt;/li&gt;&lt;li&gt;POST&lt;/li&gt;&lt;/ul&gt;雖然 HTTP 定義八個 Method之多，但是大家在 Coding Web 時只使用這兩個 Method。&lt;br /&gt;原因很簡單，因為最多人使用的 HTTP Client，也就是 Browser，只支援 GET 和 POST。所以，我們之前的 Coding，都是只用 GET 和 POST 來對 Web Resource 來做 CRUD。&lt;br /&gt;&lt;blockquote&gt;CREATE：POST  http://abc.com/users/create/&lt;br /&gt;READ：GET  http://abc.com/user/show/1&lt;br /&gt;UPDATE：POST  http://abc.com/user/update/1&lt;br /&gt;DELETE：GET  http://abc.com/user/delete/1&lt;/blockquote&gt;我們必須用部份的 URL 來表示我們對這個 Resource 的操作，這樣做也沒什麼不好，但是要知道 URL 其實是要來指定 Resource 位置的，URL 不是拿來表示 Verbs 的。而且這樣做等於我們使用四個 URL 來表示同一個 Resource，這跟一個 Resource 理論上來說只能有一個 URL 牴觸。&lt;br /&gt;&lt;br /&gt;RFC 定義的 HTTP 1.1 裡面，其實有四個 Method 是直接 Mapping 到 CRUD 的，那就是 GET，POST，PUT，DELETE。既然已經 HTTP 1.1 已經有對應好的 Method，那為什麼我們要捨近求遠，硬是要使用 GET POST 來設計出 CRUD，為什麼不用原本就規定好的 Mapping  來做 CRUD 呢？&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;沒錯，這就是 REST。讓大家不需要再捨近求遠，不需要用非 Web Standard 的方式來做 Web Development。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;REST 的詳細定義就請看 &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;Wikipedia上面的介紹&lt;/a&gt;， 本人就不詳細敘述了。在定義上來說，REST 並不等於 HTTP，REST 是一種 Architectural Style，而非一種 Standard，所以 REST 並沒有 toolkit ，也沒有 W3C Spec。相對起來，HTTP 才是一種 Standard ，有相對應的 toolkit，W3C Spec。HTTP 是一種 REST 的實做，也是最成功的實做。但是我們以實用為主，並不是那麼在乎太過細部的差別，所以以後我不會太強調 REST 跟 HTTP 兩者意義上的區分。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4622134434508933345?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/4622134434508933345/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=4622134434508933345' title='4 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4622134434508933345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/4622134434508933345'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/04/rest.html' title='REST 簡介'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-8671145780641009430</id><published>2007-04-18T13:10:00.000+08:00</published><updated>2007-04-18T14:13:42.701+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>搞清楚你的 Rails Version</title><content type='html'>目前使用 Rails 的網站，Version 分成好幾派。&lt;ul id=""&gt;&lt;li&gt;0.X&lt;/li&gt;&lt;li&gt;1.0 &lt;/li&gt;&lt;li&gt;1.1&lt;/li&gt;&lt;li&gt;1.2&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;Rails 0.X 的就是幾年前就開始在使用 Rails 的始祖，據我所知國內也是有網站還再用 0.X ，他們之所以死撐不換的原因只有一個，就是怕升級上去原本的 code 根本不相容。1.0 的時候我沒趕上，那可能要問一些長輩才知道 1.0 的模樣是怎麼樣子。&lt;br /&gt;&lt;br /&gt;我進入 Rails 圈子剛好是 1.1 的剛剛出的時代，那時候 RJS 剛剛出來，大家叫好又叫座。我也因此全新投入了 Rails，1.1 的穩定度很高，速度也不賴。 Rails .12 是今年才出的，REST 加上 has_many :through 實在非常的吸引人，不過有 benchmark 表示 Rails 1.2 在速度上輸給 Rails 1.1，不過也沒輸太多。所以綜觀起來，要使用 Rails 1.1 或是 1.2 是要看你的需求而定的，沒有一定要使用那個版本的建議。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;我現在手邊的 Project 都是用 1.1 ，而且絕大多數已經上線在跑的，短期間不太可能轉換到 1.2 。但是我一定會花很多時間在了解 1.2 的情況。也就是說，我希望能夠在我的機器上面裝 1.1 跟 1.2，有沒有辦法達成呢？&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;當然有，這很基本！！！&lt;/span&gt;&lt;br /&gt;首先，你的 gem 已經安裝了你所要求的 Rails Version，像是我希望在我的機器上面可以自由使用 1.1 或是 1.2 的 Rails，所以我的 gem 安裝情況就是&lt;br /&gt;&lt;blockquote&gt;rails (&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;1.2.3, 1.1.6&lt;/span&gt;&lt;/span&gt;)&lt;br /&gt;Web-application framework with template engine, control-flow layer,&lt;br /&gt;and ORM.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;問題來了，要怎麼一次安裝兩個以上的 version 呢？假設你的 Rails 已經安裝了 1.1.6 ，可是又要安裝 1.2.3 ，就這樣打吧。&lt;blockquote&gt;sudo gem install -v=1.2.3 rails&lt;/blockquote&gt;當然，如果你想安裝的是最新的 Rails Release，那麼這樣也是可以的&lt;blockquote&gt;sudo gem i rails&lt;/blockquote&gt;如此就可以在同一台機器上面安裝不同 version 的 rails 。&lt;br /&gt;&lt;br /&gt;確定了你的 gem 已經安裝了多個 version，我們必須了較 freeze code 的概念，很多時候我們的某個 Project 的 code 是在某個版本的 rails 開發的。當rails 出了新的 release，原本run 好好的 code 就可能出現一堆 error，所以我們必須要在這個 Project 也包入 Rails 這個 version 的 code。使用方式如下&lt;br /&gt;&lt;blockquote&gt;rake rails:freeze:edge TAG=rel_1-1-6&lt;br /&gt;rake rails:freeze:edge TAG=rel_1-2-3&lt;br /&gt;&lt;/blockquote&gt;顧名思義，你可以再 TAG 下面指定你要的 Rails Version，這個指令會把 Rails 放入 vender/rails/ 底下，以後伺服器執行前，他都會去這個資料夾尋找，如果有 vender/rails/ 的資料夾，他就不會使用系統預設的 Rails version ，而是使用已經包在這個 Rails 資料夾的 version。&lt;br /&gt;&lt;br /&gt;當然，如果我們將已經包好的 Rails Version 解除，重新使用系統預設的 Rails Version，就這樣打即可&lt;br /&gt;&lt;blockquote&gt;rake rails:unfreeze&lt;br /&gt;&lt;/blockquote&gt;他做的事情其實就只是 rm -fr vender/rails/ 資料夾而已。&lt;br /&gt;&lt;br /&gt;最後一點，如果你不確定你的 Rails Package 到底使用那個 Version 的 Rails ，你可以打入&lt;br /&gt;&lt;blockquote&gt;ruby script/about&lt;/blockquote&gt;&lt;br /&gt;他會跟你講的一清二楚的。&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8671145780641009430?l=lightyror.thegiive.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lightyror.thegiive.net/feeds/8671145780641009430/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5166551042886235322&amp;postID=8671145780641009430' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8671145780641009430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5166551042886235322/posts/default/8671145780641009430'/><link rel='alternate' type='text/html' href='http://lightyror.thegiive.net/2007/04/rails-version.html' title='搞清楚你的 Rails Version'/><author><name>thegiive</name><uri>http://www.blogger.com/profile/01571087539375805403</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5166551042886235322.post-5920200597043887275</id><published>2007-04-16T23:27:00.000+08:00</published><updated>2007-04-16T23:36:49.624+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>[Ruby] recursive lambda</title><content type='html'>[Ruby] recursive lambda&lt;br /&gt;&lt;br /&gt;==本文連同引文同步載於 &lt;a href="http://www.ptt.cc/bbs/Ruby/index.html" target="_blank"&gt;ptt Ruby&lt;/a&gt; 板、&lt;a href="http://lightyror.thegiive.net/" target="_blank"&gt;LightyRoR&lt;/a&gt;、&lt;a href="http://www.godfat.idv.tw/" target="_blank"&gt;飽和脂肪星&lt;/a&gt;（&lt;a href="http://blog.godfat.idv.tw/" target="_blank"&gt;星之一角&lt;/a&gt;&lt;a href="http://www.godfat.idv.tw/viewforum.php?f=11" target="_blank"&gt;備份區&lt;/a&gt;）==&lt;br /&gt;&lt;br /&gt;很抱歉最近狀況真的是相當糟糕，導致很多事情都沒做或是沒做好。雖然以後大概也不會比較好。這樣講講就沒關係嗎？當然不是，只是替自己找一點比較能安心的藉口吧。另外本文有任何錯誤歡迎指出。&lt;br /&gt;&lt;br /&gt;==本文開始==&lt;br /&gt;&lt;br /&gt;我一直覺得 Ruby 缺少一個類似 self 的東西，用來表達現在這個 function/method. 這個東西有什麼用呢？其實我也不知道有什麼用，就只是單純覺得好像少了這種東西。最直覺的例子，恐怕就是具有遞迴能力的 lambda function. 我曾在 ptt Ruby 板發過一篇文，講 &lt;a href="http://www.nyx.net/~gthompso/quine.htm" target="_blank"&gt;quine&lt;/a&gt;（self-reproducing programs），後來我用了 &lt;a href="http://rubyforge.org/projects/seattlerb" target="_blank"&gt;Ruby2Ruby&lt;/a&gt;, 寫了像這樣的結果：（&lt;a href="http://www.godfat.idv.tw/viewtopic.php?p=1330#1330" target="_blank"&gt;飽和脂肪星有該文的備份&lt;/a&gt;（通常連不上））&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#!/usr/bin/ruby&lt;br /&gt;&lt;br /&gt;require 'rubygems'&lt;br /&gt;require 'ruby2ruby'&lt;br /&gt;&lt;br /&gt;(a = proc {&lt;br /&gt;  puts("#!/usr/bin/ruby")&lt;br /&gt;  puts&lt;br /&gt;  puts("require 'rubygems'")&lt;br /&gt;  puts("require 'ruby2ruby'")&lt;br /&gt;  puts&lt;br /&gt;  print("(a = ")&lt;br /&gt;  print(a.to_ruby)&lt;br /&gt;  print(").call")&lt;br /&gt;}).call&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;最蠢的地方是明明都用 lambda(proc) 了，我卻還得把 lambda 的結果記起來留待以後使用。這樣實在是有點無趣。我希望我可以寫：&lt;br /&gt;&lt;br /&gt;lambda{ print(this.to_ruby); print(".call") }.call&lt;br /&gt;&lt;br /&gt;這樣不是帥氣多了嗎？於是我開始試著思索實作這東西的可能。接著我忽然想到，所謂 this 不正是指在 call stack 最上端的 function/method 嗎？因為當我們執行到這個 function/method 時，this 一定是指同一 function, 不可能忽然去指涉其他 function, 而另外一個 function 進 call stack 時，不把他解掉也不可能會執行到 this. 於是可以把 this 寫成一個 function, 不吃任何引數，回傳一個 Proc/Method 代表正在 call stack 頂端的那個 function.&lt;br /&gt;&lt;br /&gt;而我記得 Ruby 是有方法可以去存取 call stack... 雖然好像是用很蠢的方法，也確實是有點蠢，但總之可以用模擬的。隨意 &lt;a href="http://www.google.com/" target="_blank"&gt;google&lt;/a&gt; 了一下，找到一個很簡單的方式，就是用 set_trace_func, 丟一個 callback 進去，於是 Ruby 在各個 function 間做動作的時候，都會呼叫這個 callback. 感覺就是效率會變狂差，不過呢，至少暫時是可以用的。&lt;br /&gt;&lt;br /&gt;接著可以利用 Thread.current[:symbol] 來儲存 current thread call stack info, 任何 function call 時，push 資料進這個假的 call stack, function return 時，pop 資料出來。這樣就有一個很簡單的 call stack info 可以用了。&lt;br /&gt;&lt;br /&gt;以下程式歡迎任意使用，licensed under Apache License 2.0, 複製到檔案用的話希望可以把以下這段 copy 到檔案最前面… XD&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#    Copyright (c) 2007, Lin Jen-Shin（a.k.a. godfat 真常）&lt;br /&gt;#&lt;br /&gt;#    Licensed under the Apache License, Version 2.0 (the "License");&lt;br /&gt;#    you may not use this file except in compliance with the License.&lt;br /&gt;#    You may obtain a copy of the License at&lt;br /&gt;#&lt;br /&gt;#        &lt;a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank"&gt;http://www.apache.org/licenses/LICENSE-2.0&lt;/a&gt;&lt;br /&gt;#&lt;br /&gt;#    Unless required by applicable law or agreed to in writing, software&lt;br /&gt;#    distributed under the License is distributed on an "AS IS" BASIS,&lt;br /&gt;#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;br /&gt;#    See the License for the specific language governing permissions and&lt;br /&gt;#    limitations under the License.&lt;br /&gt;&lt;br /&gt;module Kernel&lt;br /&gt;  # 由於 google 到的參考程式把抓 call stack 叫 invoker,&lt;br /&gt;  # 所以這裡沿用他的名字。有個常數比較容易看懂程式在做什麼。&lt;br /&gt;  INVOKER_EVENT   = 0&lt;br /&gt;  INVOKER_FILE    = 1&lt;br /&gt;  INVOKER_LINE    = 2&lt;br /&gt;  INVOKER_MSG     = 3&lt;br /&gt;  INVOKER_BINDING = 4&lt;br /&gt;  INVOKER_CLASS   = 5&lt;br /&gt;&lt;br /&gt;  # -1 就是 top 的意思囉&lt;br /&gt;  def invoker levels = -1&lt;br /&gt;    st = Thread.current[:callstack]&lt;br /&gt;    # st 有可能是 nil, 如果 invoker 先被 call 到的話。&lt;br /&gt;    # 雖然我不知道什麼時候會發生這種事…。levels - 2 的原因是：&lt;br /&gt;    # 0(stack bottom) =&gt; function that you called(this is what we want)&lt;br /&gt;    # 1               =&gt; Kernel#invoker&lt;br /&gt;    # 2               =&gt; Array #[]&lt;br /&gt;    # 所以去掉額外不要的額外兩個資訊。&lt;br /&gt;    st &amp;&amp; st[levels - 2]&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def this&lt;br /&gt;    # 因為多 call 了 this, 所以要再多去掉一個額外資訊。&lt;br /&gt;    info = invoker(-2)&lt;br /&gt;    # 這邊我本來寫成 lambda 的形式，可以正確執行，但有一個狀況&lt;br /&gt;    # 卻是失敗的。就是 lambda{yield}.call{} 這樣是會 error 的 :(&lt;br /&gt;    # 試了多次還是找不到 Proc.call 吃 block({}) 的方法，只好改寫&lt;br /&gt;    # 成用 Method 的形式。不知為何，Method 就可以正確使用 block...&lt;br /&gt;    eval("self", info[INVOKER_BINDING]).method(info[INVOKER_MSG])&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;set_trace_func lambda{ |*args|&lt;br /&gt;  case args[INVOKER_EVENT]&lt;br /&gt;    # 可能的有 call 和 c-call, 都是 function&lt;br /&gt;    when /call$/&lt;br /&gt;      # 這邊我搞不清楚到底是誰會先被 call, 是 call 還是 return?&lt;br /&gt;      # google 來的是把初始化寫在 call 裡，可是我測試都顯示是在&lt;br /&gt;      # return 上，所以反而是 return 的地方需要初始化。或是乾脆&lt;br /&gt;      # 全部拉出來在最上面初始化也可以 :)&lt;br /&gt;      (Thread.current[:callstack] ||= []).push args&lt;br /&gt;      # 同上可能有 return 和 c-return&lt;br /&gt;    when /return$/&lt;br /&gt;      (Thread.current[:callstack] ||= []).pop&lt;br /&gt;  end&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;以上不管有沒有問題，都可以來看一下我額外寫的幾個 unit test, 參考一下幾個我目前想到的用法。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;require 'test/unit'&lt;br /&gt;&lt;br /&gt;class TestThis &lt; Test::Unit::TestCase&lt;br /&gt;  def test_fact&lt;br /&gt;    assert_equal(120, fact(5))&lt;br /&gt;    assert_equal(3628800, fact(10))&lt;br /&gt;    # 試用 recursive lambda&lt;br /&gt;    assert_equal(5040, lambda{|n| return n*this[n-1] if n&gt;0; 1}[7])&lt;br /&gt;  end&lt;br /&gt;  def fact n&lt;br /&gt;    # 恐怕是最常見的用法&lt;br /&gt;    return n*this[n-1] if n &gt; 0&lt;br /&gt;    1&lt;br /&gt;  end&lt;br /&gt;##&lt;br /&gt;  def test_pass_around&lt;br /&gt;    # 這邊流程可能很怪，因為只是我隨便寫的，單純測試正確性罷了。&lt;br /&gt;    assert_equal(method(:pass_around_forward), pass_around.call(lambda{|v| v}))&lt;br /&gt;  end&lt;br /&gt;  def pass_around mode = 'pass'&lt;br /&gt;    case mode&lt;br /&gt;      when 'pass'&lt;br /&gt;        pass_around_forward this&lt;br /&gt;      else&lt;br /&gt;        'value'&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  def pass_around_forward func&lt;br /&gt;    assert_equal('value', func['value'])&lt;br /&gt;    this&lt;br /&gt;  end&lt;br /&gt;##&lt;br /&gt;  def test_with_block&lt;br /&gt;    # 同上，流程亂寫的，單純測試正確性。&lt;br /&gt;    with_block{|b| assert_equal('value', b['value'])}&lt;br /&gt;  end&lt;br /&gt;  def with_block mode = 'pass', &amp;block&lt;br /&gt;    case mode&lt;br /&gt;      when 'pass'&lt;br /&gt;        block[this]&lt;br /&gt;      else&lt;br /&gt;        'value'&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;##&lt;br /&gt;  def test_more_args&lt;br /&gt;    # Proc 就是死在這個測試，block 展開怎麼做都失敗 :(&lt;br /&gt;    # 改成 Method 後這邊就可以通過測試了。&lt;br /&gt;    more_args('get_this'){}.call('call', 1, 2, 3, 4, 5, &amp;lambda{6})&lt;br /&gt;    more_args('get_this'){}.call('call', 1, 2, 3, 4, 5){6}&lt;br /&gt;  end&lt;br /&gt;  def more_args mode, a1=nil, a2=nil, a3=nil, *as, &amp;block&lt;br /&gt;    case mode&lt;br /&gt;      when 'get_this'&lt;br /&gt;        this&lt;br /&gt;      else&lt;br /&gt;        assert_equal(1, a1)&lt;br /&gt;        assert_equal(2, a2)&lt;br /&gt;        assert_equal(3, a3)&lt;br /&gt;        assert_equal(4, as[0])&lt;br /&gt;        assert_equal(
