tag:blogger.com,1999:blog-51665510428862353222009-06-16T23:28:07.789+08:00Lighty RoR介紹 Ruby,Ruby on Rails,JRubythegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.comBlogger361125tag:blogger.com,1999:blog-5166551042886235322.post-26891713811245848212009-01-09T17:49:00.006+08:002009-01-09T18:08:09.669+08:00ReCAPTCHA 與 ReCAPTCHA Rails Plugin我們不管是註冊,或是去便當狗下載東西,都會有一張圖裡面有字,然後要你 keyin 正確的字。那個東西叫做 CAPTCHA。 CAPTCHA 是 ”Completely Automated Public Turing test to tell Computers and Humans Apart”的縮寫,主要用途是為了防止 robot Spam所做的手段。我看過最討厭,最難懂得 CAPTCHA 就是 Google 的 CAPTCHA,每次看都要硬猜個一兩次才會對,大概是他們整天被 Spam 攻擊,只好連真人都開始防堵 XD<br /><br />而什麼是 ReCAPTCHA 呢? ReCAPTCHA 是卡內基美隆大學的一項計畫,由卡內基美濃學院資訊科學系執行。主要目的是為了加快實體文本數位化而作的一個手段,一般來說實體文本數位化需要的是數位掃描的技術,但是還是有很大量的書籍裡面的字礙誨難懂,有可能是紙張變質,也有可能是以前人的書寫習慣不公整(就是講我XD),這個時候就需要人力去辨識字的內容,並且給予機器正確的 return,順便 training 數位技術 Algorithm。很可惜的是,人力是要錢的。所以他們想出一個聰明到嚇死人的方式來處理這個問題。<br /><br />他們開發了一個網站,叫做 ReCAPTCHA 。裡面提供 CAPTCHA API ,讓網站開發者當需要 CAPTCHA 的技術時候,可以直接 Implement 這個 API,而不需要依賴自己重新開發 CAPTCHA 技術。他們並且號招很多志願者開發各種語言版本的 API,來加速網站開發者 implement ReCAPTCHA的速度。以下是 ReCAPTCHA 的截圖<br /><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"><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" /></a><br /><br /><br />那為何他要免費提供這樣的服務呢?我們來仔細看他的技巧來自於 CAPTCHA 圖片本身,ReCAPTCHA 的圖片都是兩個英文字<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_8vS0KjIsbko/SWceGTGzLFI/AAAAAAAAAqU/Ize6oBtn3N0/s1600-h/Modern-captcha.jpg"><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" /></a><br /><br /><br />左邊的字 following 是他們已經確認掃描正確的字,右邊的 finding 是他們還無法用掃描確定意義的字。當使用者在 keying 認證碼的同時,他只要確定左邊的「following」是正確的,他們就認為是正確的 input,予以放行,但是使用者不是也 keyin 右邊的字嗎?那那個 input,ReCAPTCHA網站就視為你順手幫我做的影像校正,存到資料庫裡面。網站開發者免費得到 CAPTCHA 技術,ReCAPTCHA 獲得數以百萬記的免費人力幫忙校正,是個典型的雙贏局面。<br /><br />至於 Ruby 裡面有沒有 ReCAPTCHA API 呢?當然有。ReCAPTCHA for Ra ils 主頁在此。安裝方式就是<br /><br /><div class="CodeRay"><br /> <div class="code"><pre>ruby script/plugin install git<span style="color:#A60">:/</span>/github.com/ambethia/recaptcha.git<br /></pre></div><br /></div><br /><br />安裝完成之後,你必須要先去 ReCAPTCHA 網站註冊,他會給你一個 PUB key 跟 Private key,將他記錄在 Rails 的 config/enviroment.rb 裡面<br /><br /><table class="CodeRay"><tr><br /> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt><br /></tt>2<tt><br /></tt></pre></td><br /> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="co">ENV</span>[<span class="s"><span class="dl">'</span><span class="k">RECAPTCHA_PUBLIC_KEY</span><span class="dl">'</span></span>] = <span class="s"><span class="dl">"</span><span class="k">public_key_goes_here</span><span class="dl">"</span></span> <tt><br /></tt><span class="co">ENV</span>[<span class="s"><span class="dl">'</span><span class="k">RECAPTCHA_PRIVATE_KEY</span><span class="dl">'</span></span>]= <span class="s"><span class="dl">"</span><span class="k">private_key_goes_here</span><span class="dl">"</span></span><tt><br /></tt></pre></td><br /></tr></table><br /><br />接下來就是使用 ReCAPTCHA 啦,你要將 ReCAPTCHA 放在你需要的地方,這邊唯一要注意的地方在於你必須要放在 form 裡面<br /><table class="CodeRay"><tr><br /> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt><br /></tt></pre></td><br /> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><<span class="s"><span class="dl">%=</span><span class="k"> recaptcha_tags %> <tt><br /></tt></span></span></pre></td><br /></tr></table><br /><br /><br />接下來要驗證對方 keyin 的認證碼正不正確,我們只需要在相關的 controller 放入<br /><br /><table class="CodeRay"><tr><br /> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt><br /></tt>2<tt><br /></tt>3<tt><br /></tt>4<tt><br /></tt>5<tt><br /></tt></pre></td><br /> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="r">if</span> verify_recaptcha <tt><br /></tt><span class="c">#正確的處理方式 </span><tt><br /></tt><span class="r">else</span> <tt><br /></tt><span class="c"># 錯誤的處理方式 </span><tt><br /></tt><span class="r">end</span> <tt><br /></tt></pre></td><br /></tr></table><br /><br />然後,沒啦,很簡單吧!!!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-2689171381124584821?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-73706525663437899482008-12-26T17:31:00.001+08:002008-12-26T17:32:37.118+08:00File_Column 在 Rails 2.2 遇到問題以及解法從<a href="http://www.javaeye.com/topic/277860">這裡</a>找到的解法,File_column 在升級 Rails 2.2 會遇到問題<br /><div class="CodeRay"><br /> <div class="code"><pre>uninitialized constant <span style="color:#036; font-weight:bold">FileColumn</span>::<span style="color:#036; font-weight:bold">ClassMethods</span>::<span style="color:#036; font-weight:bold">Inflector</span> <br /></pre></div><br /></div> <br />解決方式就是找到 vender/plugins/file_column/lib/file_column.rb 的 619行<br /><div class="CodeRay"><br /> <div class="code"><pre>my_options = <span style="color:#036; font-weight:bold">FileColumn</span>::init_options(options, <br /> <span style="color:#036; font-weight:bold">Inflector</span>.underscore(<span style="color:#038; font-weight:bold">self</span>.name).to_s, <br /> attr.to_s) </pre></div><br /></div> <br />改成 <br /><div class="CodeRay"><br /> <div class="code"><pre>my_options = <span style="color:#036; font-weight:bold">FileColumn</span>::init_options(options,<br /> <span style="color:#036; font-weight:bold">ActiveSupport</span>::<span style="color:#036; font-weight:bold">Inflector</span>.underscore(<span style="color:#038; font-weight:bold">self</span>.name).to_s,<br /> attr.to_s) </pre></div><br /></div><br />即可。主要原因是 Rails Core 漸漸有 Namespace 概念(不是本來就要有了嗎XD),所以之前可以 work 的 plugin code 現在都要修改成比較好的寫法。<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7370652566343789948?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com1tag:blogger.com,1999:blog-5166551042886235322.post-55341978920274836542008-12-24T15:52:00.001+08:002008-12-24T15:53:45.564+08:00金剛合體:Merb 將要 merge 到 Rails 3<p>我以為 Rails 2.2 已經很有創意了,弄出很多新東西(or 應該做的東西) ,Rails 3 到底要做啥東西才能夠讓人家驚訝了呢?噹噹,我發現到 Rails 還是嚇到我了 。</p><p>Big news 就是 Merb 跟 Rails 3 預計在 2009 的 Rails conf Merge 起來,Merb 作者 wycats( Yehuda Katz)會加入 Rails Team。請注意,我知道很瘋狂,不過這個消息已經經過 <a href="http://weblog.rubyonrails.com/2008/12/23/merb-gets-merged-into-rails-3">Rails</a> And <a href="http://yehudakatz.com/2008/12/23/rails-and-merb-merge/">Merb</a> 雙方證實了。</p><p>DHH 指出這次的 Merge 有幾點工作要做</p><ol> <li>Rails core:Rails 是一個 full stack framework ,不過他要參考 merb ,讓人很簡單的做出 rails myapp–core 和 rails myapp—flat</li> <li>效能強化</li> <li>Framework 解構:雖然 Rails 預設依舊是 ActiveRecord 當 ORM,不過你也可以選擇 data mapper,Sequel,Template 可以選擇 HAML,AJAX 可以選擇 jquery</li> <li>Rigorous API:反正就是要解決 Rails 一升級 plugin 就炸掉的問題</li></ol><p>怎麼看起來像是又生出一個 Merb ?</p><p>我來猜猜,DHH 認為 Merb 社群長久以來的堅持是對的,而 Rails 社群漸漸走錯路, DHH 眉頭一皺,認為案情並不單純,利用自己還很龐大的力量吃掉 Merb ,然後順便導正 Rails 該走的路。</p><p>It is not good news , and it is also not bad news,It's AMAZING news。</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-5534197892027483654?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com1tag:blogger.com,1999:blog-5166551042886235322.post-33883692641970391452008-12-22T23:46:00.000+08:002008-12-22T23:51:57.540+08:00Ruby Memory Leak 巨大問題以及解決方式<p>Ruby Memory Leak 一向是一個難以解決的議題,不過在今年 11月12日的 <a href="http://www.nabble.com/-ruby-core%3A19846---Bug--744--memory-leak-in-callcc--to20447794.html">Mailing List</a> 裡面有人提出一個重要的問題, Ruby 的 callcc 在使用中產生相當明顯的 Memory Leak。後來有高手 <a href="http://www.nabble.com/Re%3A--ruby-core%3A19945---Bug--744--memory-leak-in-callcc--p20533504.html">Brent Roman 發表他的發現</a>。他原本再 ARM CPU 上面開發他的 Ruby Robot 程式(Ruby 1.6.8),他的機器人上面只有 32 MB 的 Memory,不過他的 Ruby 程式一天就會吃掉 20MB 的 Memory,經過他的 hack ,現在他的 Ruby 程式已經穩定在 10MB 以下,他發現 Ruby Memory Leak 很大部分在於 pointer ,跟 callcc 的使用上,Javaeye 上面有對於這個問題的<a href="http://www.javaeye.com/news/4407-ruby-memory-leak-culprit---the-ghost-references-to-stack">詳細中文翻譯</a>。</p><br /><p>Matz 知道之後,相當鼓勵 Brent 將他的 Patch 放到 Ruby 上面,如今他的 Patch 終於發佈,他是根據 Ruby 1.8.7-p72 做的 Patch ,又由於他在 Monterey Bay Aquarium Research Institute工作,所以叫做 <a href="http://sites.google.com/site/brentsrubypatches/">1.8.7-p72 MBARI Patch</a>,目前處於 Alpha 版本。他發現經過他的 hack 之後,對於 Memory Leak 上有相當大的解決。根據他的用 Ruby 預設的 Test Case 的結果,他發現 Memory 消耗從 97MB 降低到 57 MB,JavaEye 也利用他們的程式做測試,Javeeye Fcgi Memory 消耗量從 129MB 降低為 99MB。</p><br /><p>相當不錯的結果,期待納入 Ruby 1.8.7 的那一天。</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-3388369264197039145?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-83207445239124875062008-12-16T22:24:00.003+08:002008-12-16T22:50:28.625+08:00Rails 2.2 在 Windows 上面有關 mysql Gem 的問題今天要幫公司同事灌 Windows 上面 Rails ,發現安裝 mysql gem 出了點問題 ,本來是不用管,直接使用 Rails 附帶的 Mysql, 不過自從 Rails 2.2 之後,Rails 原本附帶的 mysql adaptor 已經移除掉adaptor,所以被迫得安裝 MySQL Gem 。<div><div><br /><blockquote><div><span class="Apple-style-span" style="color:#333333;">The bundled mysql.rb driver has been removed from rails 2.2. Please<br />install the mysql gem and try again: gem install mysql."</span></div></blockquote></div><div>當我 gem i mysql,本來是沒問題的,不過現在不知道 gemspec 那裡改壞了,導致出現問題</div><blockquote><span class="Apple-style-span" style="color:#333333;">Installing ri documentation for mysql-2.7.3-x86-mswin32...<br />Installing RDoc documentation for mysql-2.7.3-x86-mswin32...<br />ERROR: While generating documentation for mysql-2.7.3-x86-mswin32<br />... MESSAGE: Unhandled special: Special: type=17, text=""<br />... RDOC args: --op</span><!-- $Id: README.html,v 1.20 2006-12-20 05:31:52 tommy Exp $ --></blockquote>所以第一個問題解法就是不搞 RDOC,直接使用 <b>gem i mysql --no-ri --no-rdoc <span class="Apple-style-span" style="font-weight: normal; ">安裝</span></b></div><div><br /></div><div>當我以為已經解決的時候,沒想到出現第二個 Error</div><blockquote><span class="Apple-style-span" style="color:#333333;">This error occurred while loading the following files: mysql</span></blockquote><div>靠,Rails 2.2 + Windows 還真多災多難,解決方式根據<a href="http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/e6e656b52289ae45?pli=1">這裡</a>,裡面說到要把 MySQL 帶的 libmysql.dll 複製一份過去到 ruby\bin 底下</div><div><blockquote><div><span class="Apple-style-span" style="color:#333333;">copy mysql\bin\dll\libmysql.dll ruby\bin\</span></div><div><div></div></div></blockquote></div><div><div>我使用的是 Instant Rails ,所以 MySQL 跟 Ruby 都放在同一個資料夾下面,如果安裝方式不同請自行處理。</div><div><br /></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8320744523912487506?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-72561755902940663832008-10-26T11:28:00.003+08:002008-10-26T12:18:17.217+08:00Rails 2.2 :多個願望一次達成...購物專家:來來,我們現在請到 Rails 副總來本購物台,想請問副總對於這次 Ruby on Rails 2.2 來本台銷售,帶來了什麼好康。<br /><br />副總:這次的 Rails 2.2 可以說是本 Rails 產品史上最大的升級,可以說是把所有想的到聽的到看的到的問題都一次解決,保證這次不買你就是笨蛋,還去寫 PHP 或是 Java 只能祝福你。<br /><br />購物專家:啥,那麼可怕,那我想問問,有關之前被人詬病的 Rails <span style="font-weight: bold;">國際化</span>的部份有何加強。<br /><br />副總:記得上次我們來的時候怎麼講的?Rails 要國際化必須要 Gettext 或是 Plugin 來解決對不對。今天帶來的第一個優惠, Rails 2.2 直接<span style="font-weight: bold;">內建 i18n</span> 給你。如果有問題的話,請到<a href="http://rails-i18n.org/">Rails i18n</a>來看看怎麼實作。基本上是寫一個 yaml 就可以解決了。<br /><br />(罐頭歡呼聲)<br /><br />購物專家:什麼,直接內建 i18n ,那其他 Framework 不是少了一個古老的暴點可以笑 Rails 了嗎?你們上面業績衝的很兇歐,優惠送那麼大。那以前最讓人詬病的<span style="font-weight: bold;">效能</span>問題呢?<br /><br />副總:抱歉,其他家公司,你們災洗了。我們這次直接升級到<span style="font-weight: bold;"> Ruby 1.9</span>,讓你們享受 19 倍的效率提昇。<span style="font-style: italic; color: rgb(102, 102, 102);">(註:購物台都是隨便唬爛的,有提昇是沒錯,有沒有 19 倍就不知道XD)</span><br /><br />(罐頭歡呼聲)<br /><br />購物專家:什麼什麼,你們直接支援效率打敗 Python 2.5 的 Ruby 1.9 呀,那不就是筆記型電腦加 Ram 再加 ssd 這樣誇張歐。這樣你們不會獲利下降嗎?<br /><br />副總:沒關係,只要可以服務購物台,我們可以流血犧牲<br /><br />購物專家:導播,各位觀眾,我已經快受不了,那麼好的優惠,那麼好的內容只在今天的 XX 購物台。現在電話所有線路忙線中,請改撥語音專線可以優先訂購。副總,已經端出那麼多了,還有啥好康的?<br /><br />副總:還有還有,我們改寫 ActiveRecord 了,支援 <span style="font-weight: bold;">connection pool</span> 摟,並且是 <span style="font-weight: bold;">ThreadSafe</span> 了。只要在 config/database.yml 裡面加上<br /><br />development:<br />___adapter: mysql<br />___username: root<br />___database: sample_development<br />___pool: 100<br />___wait_timeout: 10<br /><br />就等於以 100 connection 讓 model 讀讓你取,效能提昇直接上看 100倍 <span style="color: rgb(102, 102, 102);">(註:購物台都是隨便唬爛的,有提昇是沒錯,有沒有 100 倍就不知道XD)</span><br /><br />(罐頭歡呼聲)<br /><br />購物專家:現在耳機傳來導播的聲音,現在我們備貨數量已經真的真的很少了,大家太踴躍了,記得撥打語音專線可以省一百塊歐。副總你們還有啥優惠嗎?<br /><br />副總:我們加入了 HTTP 的 <span style="font-weight: bold;">last modified since</span> 的 support,讓上次沒有修改過的內容就直接回傳一個 empty response 回去。原本是要回傳幾百K的東西,現在至需要回傳 0 K ,效能提昇直接上看<span style="font-size:130%;"><span style="font-weight: bold;">無限大</span></span><span style="color: rgb(102, 102, 102);">(註:購物台都是.....算了,懶得講了XD )</span><br /><br />(罐頭歡呼聲)<br />(罐頭歡呼聲)<br />(罐頭歡呼聲)<br /><br />副總:ㄟㄟㄟ,導播,我的購物專家勒?<br /><br />導播:他太激動了,回去學習 Ruby on Rails 了。<br /><br />副總:ㄟㄟㄟ,那麼猴急,我還沒講完勒,<a href="http://guides.rubyonrails.org">http://guides.rubyonrails.org</a> 上線了,可以直接上去看一些 online guilde。<br /><br /><br /><br />言歸正題,此次的 Rails 2.2 真的是超乎想像的加碼再加碼,修正了很多以前的問題,也加入相當多新的功能。<br /><br />1. i18n<br />2. Ruby 1.9<br />3. connection pool<br />4. thread safe<br />5. etag and last modified since<br /><br />真的可以說是史上最大的升級 XD<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7256175590294066383?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com3tag:blogger.com,1999:blog-5166551042886235322.post-35904233839317245922008-06-25T14:43:00.000+08:002008-06-25T14:48:33.206+08:00Python Hackthon 遭到保護動物組織的抗議http://www.javaeye.com/news/2697<br /><br />http://techfaux.com/2008/06/17/peta-targets-computer-programmers-with-string-of-bizarre-protests/<br /><br />間單講就是好好的 Python Hackthon 聚會,闖入一堆 30位女生,突然全部脫光衣服,然後舉牌子「How many lives just for a coat?」,意思是要殺掉多少蛇才能有一件蛇皮大衣。<br /><br />這些天兵似乎還不知道自己在幹麼,她們大聲疾呼「We know what they’re doing in there. They’re <b>hacking pythons</b>. It’s barbaric and we won’t leave until the last snake has been saved」,秀才遇到兵,有理說不清。<br /><br /><br />改天 Ruby 聚會也有一堆人進來抗議,「停止虐待採紅寶石的勞工」怎麼辦....<br /><br /><br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-3590423383931724592?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com6tag:blogger.com,1999:blog-5166551042886235322.post-10848534835306506142008-06-06T13:56:00.002+08:002008-06-06T13:59:12.179+08:00Rails 2.1 新特色:打包 Gem<span class="Apple-style-span" style="font-weight: bold;"><span class="Apple-style-span" style="font-size: large;">顧客:</span></span>老闆, Web 2.0 網站一份,Rails 要 2.1 的,還有幫我加香菜,還有所有的 Gem Package 都要包在一起,要快點,等等 10分鐘要上 Production Server。<div><br /><span class="Apple-style-span" style="font-weight: bold;"><span class="Apple-style-span" style="font-size: large;">老闆:</span></span>好好好,馬上來,要不要順便叫個啤酒呀?<br /><br />Rails 2.1 加入了一個新功能<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"> Gem Dependencies</a> ,相當的優。像是上述需求,只需要下達<br /><blockquote><br /> $ rake rails:freeze:edge<br /> $ vi config/environment.rb<br /> $ rake gems:unpack<br /> $ rake gems:build<br /></blockquote>即可完成將 Rails 原始碼,Gems 原始碼包入到 Rails app folder 裡面,這樣 deploy 超方便呀。</div><div> <br /><strong>以下是詳細解說</strong><br /><br />$ rake rails:freeze:edge<br />把現在的Rails Version 打包入 vender/rails/<br /><br />$ vi config/environment.rb<br />把所有有關的 Gem package 加入設定檔 <br /><div class="CodeRay"><br /> <div class="code"><pre><span style=" font-weight:bold;color:#036;">Rails</span>::<span style=" font-weight:bold;color:#036;">Initializer</span>.run <span style=" font-weight:bold;color:#080;">do</span> |config|<br /><br /> <span style="color:#888;"># Require the latest version of haml</span><br /> config.gem <span style="background-;color:#fff0f0;"><span style="color:#710;">"</span><span style="color:#D20;">haml</span><span style="color:#710;">"</span></span><br /><br /> <span style="color:#888;"># Require a specific version of chronic</span><br /> config.gem <span style="background-;color:#fff0f0;"><span style="color:#710;">"</span><span style="color:#D20;">chronic</span><span style="color:#710;">"</span></span>, <span style="color:#A60;">:version</span> => <span style="background-;color:#fff0f0;"><span style="color:#710;">'</span><span style="color:#D20;">0.2.3</span><span style="color:#710;">'</span></span><br /><br /> <span style="color:#888;"># Require a gem from a non-standard repo</span><br /> config.gem <span style="background-;color:#fff0f0;"><span style="color:#710;">"</span><span style="color:#D20;">hpricot</span><span style="color:#710;">"</span></span>, <span style="color:#A60;">:source</span> => <span style="background-;color:#fff0f0;"><span style="color:#710;">"</span><span style="color:#D20;">http://code.whytheluckystiff.net</span><span style="color:#710;">"</span></span><br /><br /> <span style="color:#888;"># Require a gem that needs to require a file different than the gem's name</span><br /> <span style="color:#888;"># I.e. if you normally load the gem with require 'aws/s3' instead of</span><br /> <span style="color:#888;"># require 'aws-s3' then you would need to specify the :lib option</span><br /> config.gem <span style="background-;color:#fff0f0;"><span style="color:#710;">"</span><span style="color:#D20;">aws-s3</span><span style="color:#710;">"</span></span>, <span style="color:#A60;">:lib</span> => <span style="background-;color:#fff0f0;"><span style="color:#710;">"</span><span style="color:#D20;">aws/s3</span><span style="color:#710;">"</span></span><br /><span style=" font-weight:bold;color:#080;">end</span> </pre></div><br /></div><br /> <br />$ rake gems:unpack<br />把所有的 config 裡面設定相關的 Gem Package 都打包入 vender/gems/<br /><br />$ rake gems:build<br />非一定要用,只是如果你相關的 gem package 不一定是純 Ruby Code,有些會相關一些 C Lib,這時候就可以用這個指令來 build native gems。<br /><br /><br /></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1084853483530650614?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-43362417663011462222008-06-05T17:15:00.001+08:002008-06-05T17:15:50.572+08:00Gettext 在 Rails 2.1 下面的問題Gettext 1.19 遇到 Rails 2.1 會發生以下的問題<br /><blockquote>NoMethodError (undefined method `file_exists?' for #):<br /></blockquote><br /><br />解決方式就是寫一個 config/initializers/gettext.rb <br /><div class="CodeRay"><br /> <div class="code"><pre>require <span style="background-color:#fff0f0"><span style="color:#710">'</span><span style="color:#D20">gettext/rails</span><span style="color:#710">'</span></span><br /><span style="color:#080; font-weight:bold">module</span> <span style="color:#B06; font-weight:bold">ActionView</span><br /> <span style="color:#080; font-weight:bold">class</span> <span style="color:#B06; font-weight:bold">Base</span><br /> delegate <span style="color:#A60">:file_exists?</span>, <span style="color:#A60">:to</span> => <span style="color:#A60">:finder</span> <span style="color:#080; font-weight:bold">unless</span> respond_to?(<span style="color:#A60">:file_exists?</span>)<br /> <span style="color:#080; font-weight:bold">end</span><br /><span style="color:#080; font-weight:bold">end</span> </pre></div><br /></div><br /> <br />重起即可。<br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4336241766301146222?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com3tag:blogger.com,1999:blog-5166551042886235322.post-69148748509479000382008-05-01T08:46:00.001+08:002008-05-01T08:46:09.363+08:00Rails 2.1 RC ReleaseRails 學習之路最困難的一件事就是,社群活力太強,改版太快了。<a href="http://weblog.rubyonrails.com/2008/4/30/rails-2-1-release-candidate-is-imminent">Rails 2.1 RC Release了</a>。請到Rails最新時尚的 github 去取用。 <br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6914874850947900038?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com2tag:blogger.com,1999:blog-5166551042886235322.post-15157886317755695902008-04-22T16:14:00.000+08:002008-04-22T16:21:33.752+08:00把某資料夾的 UTF8 檔案轉成 Big5不要問我為何如此,反正 TextMate + 只能用Big5的Project 造成的。<br /><br /><div class="CodeRay"><br /> <div class="code"><pre>pwd = <span style="background-color:#f0fff0"><span style="color:#161">`</span><span style="color:#2B2">pwd</span><span style="color:#161">`</span></span>.chop<br />all_files = <span style="background-color:#f0fff0"><span style="color:#161">`</span><span style="color:#2B2">find app -type f -not -regex ".*.svn.*"</span><span style="color:#161">`</span></span><br />all_files.each <span style="color:#080; font-weight:bold">do</span> |file| <br />old_file = pwd+<span style="background-color:#fff0f0"><span style="color:#710">"</span><span style="color:#D20">/</span><span style="color:#710">"</span></span>+file.chop<br />new_file = pwd+<span style="background-color:#fff0f0"><span style="color:#710">"</span><span style="color:#D20">/big5/</span><span style="color:#710">"</span></span>+file.chop<br /><span style="background-color:#f0fff0"><span style="color:#161">`</span><span style="color:#2B2">iconv -f utf-8 -t big5 </span><span style="background: #eee"><span style="font-weight: bold; color: #888">#{</span>old_file<span style="font-weight: bold; color: #888">}</span></span><span style="color:#2B2"> > </span><span style="background: #eee"><span style="font-weight: bold; color: #888">#{</span>new_file<span style="font-weight: bold; color: #888">}</span></span><span style="color:#161">`</span></span><br /><span style="color:#080; font-weight:bold">end</span> </pre></div><br /></div><br /><br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1515788631775569590?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-59955520128387644682008-04-12T16:01:00.002+08:002008-04-13T19:24:26.452+08:00Passenger :Mod_rails for Apache 終於出世這是 Rails 登基的最後一塊基石嗎?<br /><br />不知道說了多少次,Apache 上面沒有 mod_rails,不能像是 php 一樣放上去就跑了,不過時代終於改變了,Mod_rails 出現了,他的名字叫做 <a href="http://www.modrails.com/index.html" title="Overview — Phusion Passenger (a.k.a. mod_rails)">Passenger</a>。<br /><br />他做的事情就是讓設定Ruby on Rails <strong>簡單到極點</strong>,省去所有設定繁複的設定手續,一個 Apache 就可以跑 Ruby on Rails。讓所有覺得 Ruby on Rails 設定困難的人全部閉嘴。 此東西一出,各方高手可<a href="http://www.modrails.com/testimonials.html">都是讚譽有加</a>。<br /><br />DHH : This could definitely become very popular, very fast ;)<br /><br />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.<br /><br /><strong>效能</strong><br />第一個問題是他的效能跟穩定性,跟現在市面上的 solution 有沒有得比。<br /><br />根據他們<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">自己的測試</a>,看來是有大於 Mongrel,略贏過於 Thin 的效能。 <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">Robustness 測試</a>他們宣稱跟 Mongrel 一樣穩定,勝過 thin 還有 ebb。<br /> <a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_8vS0KjIsbko/SAHtUwqMpmI/AAAAAAAAARE/YvnyPesfZoo/s1600-h/passenger_mongrel_thin_benchmark.png"><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" /></a><br /><strong>安裝方式</strong><br />既然是走簡單取向的 Apache ,那安裝方式當然要簡單點摟。只要你的 Server 上面有 Ruby / Rails / Gems / Apache2 ,那麼安裝方式就是兩下<br />1. gem i passenger<br />2. passenger-install-apache2-module<br /> <br /><strong>設定方式</strong><br />既然是走簡單取向,設定方式要更簡單,你必須在 Apache 的 httpd.conf 裡面設定<br /><blockquote><br /> LoadModule passenger_module passenger_module的預設目錄<br /> RailsSpawnServer SpawnServer路徑<br /> RailsRuby ruby路徑 <br /></blockquote><br />別擔心找不到相關路徑,<br /><img src="http://farm3.static.flickr.com/2132/2407370926_5c8c2632b6.jpg" alt="screen-capture.png" width="480" height="343" /><br />上面的圖,我們可以看到在 passenger-install-apache2-module 過程中他會自動產生相關設定檔,給你貼上去。<br /><br />剛剛是把 Rails 環境設定好,現在就是就是設定 DocumentRoot,<br /><blockquote><br /> <VirtualHost *:80><br /> ServerName www.yourhost.com<br /> DocumentRoot /rails目錄/public<br /> </VirtualHost> <br /></blockquote><br />簡單講就是要設定清楚 Document Root,設定到Rails 目錄底下的 public 資料夾。,當然他也有範例 config 檔自動生成 XD<br /><img src="http://farm3.static.flickr.com/2269/2406546183_0f5d0ccbe5.jpg" alt="screen-capture-1.png" width="480" height="350" /><br /><br /><br /><strong>讓 Rails 跑在子目錄下</strong><br />還沒測試,不過在 <a href="http://www.modrails.com/documentation/Users%20guide.html#specifying_ruby_installation" title="Passenger users guide">Doc</a> 裡面有,看來可以很簡單的跑 PHP 跟 Rails 在同一個 Apache 下面(Bravo!!!)。<br /><br /><span style="font-weight: bold;">原理</span><br />採用類似 Apache mod_fastcgi 的方式,以一個 Passenger Process 來管理所需的 Rails process 量,隨著量的大小而動態增減 Process 數目。<br /><br /><strong>結論</strong><br />目前沒有明顯的結論,說 Passenger 一定勝過 Mongrel 或是 Lighttpd+fcgi 的 Solution。不過,看到他簡單的設定檔,還有看似不錯的效能跟穩定度,真的很值得期待。<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-5995552012838764468?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com4tag:blogger.com,1999:blog-5166551042886235322.post-87738541256430353932008-04-08T08:05:00.001+08:002008-04-08T08:05:13.326+08:00解決 Textmate 中文問題沒想到我也會寫這種教學,不過既然有人問就順便講一下啦。嚴格說起來,我完全是參照<a href="http://blog.roodo.com/shinbang/archives/3264563.html">這篇網頁</a>所教學的方式。<br /><br />Textmate 對中文的實在爛到不知道怎麼說,主要有兩個問題<br />1. 沒有中文字型<br />2. 不能顯示出輸入法提示列<br /><br />要解決<strong>沒有中文字型</strong>的方式就是安裝中文字即可,請下載<a href="http://www.esnips.com/doc/f5bb5cf6-663f-46e6-80cb-0cba549c7cda/TextMateJ2"> TextMateJ2</a> 這個字型。複製到 /System/Library/Fonts/ 底下,並且雙擊安裝。安裝字型之後,就是要選擇這個字型,請到 TextMate 的 Preference -> Fonts and Colors 最下面的字型裡面選擇 TextMateJ2。<br /><br /><img src="http://farm4.static.flickr.com/3240/2397460114_f936cf1ef3.jpg" width="399" height="480" alt="screen-capture.png" /><br /><br /><br />要解決<strong>不能顯示輸入法提示列</strong>就是安裝 <a href="http://hetima.com/textmate/CJKInput20061110.zip">CJK-Input.tmplugin</a> 。解開後就直接點 CJK-Input.tmplugin,他好像就會直接安裝了。 <br /><br />成品就是如底下圖。字型會擠擠的,這是沒辦法的事情。唯一解決方案就是等 TextMate 2 出。<br /><img src="http://farm3.static.flickr.com/2170/2396628569_996a62a13a.jpg" width="480" height="237" alt="screen-capture-1.png" /><br /><br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8773854125643035393?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com2tag:blogger.com,1999:blog-5166551042886235322.post-43397579281611507732008-04-08T00:10:00.000+08:002008-04-08T07:46:45.363+08:00JRuby 1.1 ReleaseJRuby 1.1 已經 Release 了,1.0到1.1最主要的不同是在「效能」的成長。JRuby 1.1 在很多 Benchmark 已經超越了 Ruby 1.8,甚至有些也贏過了Ruby 1.9。主要的修改有 <br /><br />1. Ruby code 可以 compile 成 Java Bytecode<br />2. Regular expression engine 改成 Oniguruma<br />3. 效能的進步以及相容性的進步<br /><br />Ruby compile 成 Java Bytecode 一共有兩種模式(AOT或是JIT mode)。 <br /><br /><strong>JIT Mode </strong>是預設,代表他會經過一段時間才會運轉到 compile Mode , <a href="http://wiki.jruby.org/wiki/JRuby_Internal_Design">JRuby Wiki</a> 建議是 跑20次就自動到 JIT Mode 去。<br /><br /><strong>AOT Mode</strong> 可以將 Ruby code compile 成 Java 的 .class 檔案。如果想要直接用 Java 去執行,要裝 JRuby.jar ,還有 asm-3.0.jar ,jna.jar。 <br /><br />下載連結:<a href="http://dist.codehaus.org/jruby/jruby-bin-1.1.zip">http://dist.codehaus.org/jruby/jruby-bin-1.1.zip</a> <br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4339757928161150773?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-47942968349002829282008-04-04T18:24:00.001+08:002008-04-04T18:24:49.070+08:00更換主力 Editor ,改成 TextMate這是一個困難的決定,不過是一個對的決定。<br /><br />當我被某人勸說,不小心 Download 下來 TextMate 試用,彷彿打開所謂的禁忌之門,不久我就淪陷啦。我已經正式切換到 TextMate 上面了,vim 已經被冷落一週以上了。<br /><br />你問我 textmate 好在哪裡,我只能說調性很合我的感覺。<br /><br />是的,他有一卡車的缺點。這是我第一個花錢買的 Editor,第一個遇到居然連 Big5 都不能編輯的 Editor(他只接受 Unicode),也就是我要用 Vim 繼續處理 Big5 的 Project @@!。第一個連打中文字都要 Plugin 的軟體。<br /><br />不過,該怎麼說呢。<br /><br />Vim 是初戀情人,我用他用了5年,他對我有滿滿的回憶。Textmate 就是有很多缺點,但是卻愛的死心塌地,愛的轟轟烈烈的愛人吧。<br /><br />如果這就是愛<br />在轉身就該勇敢留下來<br />就算受傷 就算流淚<br />都是生命裡溫柔灌溉~~~ 出自『如果愛」這首歌<br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4794296834900282928?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com3tag:blogger.com,1999:blog-5166551042886235322.post-87180482020641596682008-04-04T02:45:00.008+08:002008-04-04T04:59:15.971+08:00Rack - 小架子立大功最近 Ruby Web Framework 界出現了很多新面孔:<br /><a href="http://ramaze.net/">Ramze</a>, <a href="http://sinatra.rubyforge.org/">Sinatra</a>,<a href="http://rubywaves.com">Waves</a>, <a href="http://halcyon.rubyforge.org/">Halcyon</a> ,還有 4/1 才發佈的下一代 framework ==> <a href="http://antoniocangiano.com/2008/04/01/announcing-ruby-on-crack/">Ruby on Crack!!</a><br /><br />這些 framework 各有各的特點,除了為原本被 Rails 一統天下的 web 開發增添了新的風貌,也說明了 Ruby 社群的活躍。而他們(除了太神奇的 Crack 之外)的背後的大功臣,就是今天的主題: <b><a href="http://rack.rubyforge.org/">Rack</a></b>。<br /><br /><h3>Rack 到底是何方神聖呢?</h3><br />每個 web framework 最後一定要接回去 web server 。方法有很多,有人喜歡老牌的 Fastcgi ,有人愛用<a href="http://mongrel.rubyforge.org/">雜種狗</a>,有人要像 mac book air 一樣<a href="http://code.macournoyer.com/thin/">薄</a>,有人說<a href="http://ebb.rubyforge.org/">退潮</a>最快。<br /><br />新的 framework 一直冒,新的 web server 一直來,每個人都要重新寫把兩者接起來的 code 實在太累了, Rack 就是為了解決這個問題而出現的。<a href='#footnote1' style="font-size:60%;">(1)</a><br /><br /><a href="http://www.flickr.com/photos/23796678@N04/2385302361/" title="Flickr 上 donkeydragbamboo 的 Rack"><img src="http://farm3.static.flickr.com/2251/2385302361_39aafe237b.jpg" width="400" height="256" alt="Rack" /></a><br /><br />Web 程式講白了很簡單,就是拿 request 然後回 response。Rack 就是把各種 web server 的 request 和各種 framewrok 的 response 用統一的介面來處理。那麼這個統一的介面是什麼呢?<br /><br />一句話<br /><pre style='color:#000000;background:#ffffff;'><br /><span style='color:#400000; '>lambda</span> <span style='color:#800080; '>{</span> |env| <span style='color:#808030; '>[</span><span style='color:#008c00; '>200</span>, <span style='color:#800080; '>{</span><span style='color:#800080; '>}</span>, 'Hello World!' }</pre><br />首先, Rack 會將 request 傳給要處理這個 request 的物件的 call 函式。這個例子中,處理 request 的物件就是 lambda。(當然你可以用一般的物件,只要它有 call 這個 method 就行了。)<br />例子中的 env 就是 request,它是一個 hash ,裡面包含了類似 CGI Environment 變數,像是 PATH_INFO,QUERY_STRING 等等的東西。<br /><br />而 call 的回傳值,會被當成 response 傳回去給 web server。這個回傳值必需是包含三個元素的 Array: status, headers 和 body。<br /><br />原本 N 個 framework 和 M 個 web server ,要寫出 NxM 個 Adapter。而有了 Rack 後,大家只要對 Rack 的介面做 Adapter ,複雜度馬上減少為 N+M 了!<br /><br />如此一來,不用一直重新實做橋接的邏輯,可以把心思放在 framework 本身的設計上。有了 rack ,相信 ruby 的 web 開發會更為有趣。<br /><br />下一篇再來實際寫些 code 吧。<br /><br /><a name='footnote1' ></a><br />這張圖的 idea 是從<a href="http://macournoyer.wordpress.com/2007/12/14/rack-the-framework-framework/">這裡</a>來的...<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8718048202064159668?l=lightyror.thegiive.net'/></div>contagionhttp://www.blogger.com/profile/13677354681517903830noreply@blogger.com4tag:blogger.com,1999:blog-5166551042886235322.post-14262809258415797422008-04-01T08:49:00.000+08:002008-04-01T08:50:01.810+08:00[連結文] 為何有些 Java EE/J2EE 的專案是沒效率的,至少是效率低下的<a href="http://www.adam-bien.com/roller/abien/entry/why_some_of_the_java">原文連結</a>在此,要看<a href="http://www.javaeye.com/topic/177070?page=1">簡體翻譯</a>在此。光是第一句我就笑死了。<br /><br />我想到一句話,「教授是將簡單的事情變得很複雜,天才是把複雜的事情變得很簡單」。<br /><br /><br /><br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1426280925841579742?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-84268488000277793002008-03-31T16:34:00.002+08:002008-03-31T16:35:37.344+08:00Rails 2.0 使用 Big5 編碼沒想到我的有生之年居然還會使用到 Big5!!!<br /><br />沒錯,基於機緣巧合,我碰到了一個需要使用 Big5 資料庫,網頁也是 Big5 顯示的request。所以我必須匿天而行,強迫 Rails 2.0 使用 Big5。方法很簡單,<br /><br />config/enviroment.rb 裡面加入<br /> config.action_controller.default_charset = "Big5"<br /><br />config/database.yml記得加入<br />development:<br /> host: xxx<br /> adapter: mysql<br /> database: lala<br /> port: 3306<br /> username: root<br /> password: <br /> encoding: Big5<br /><br />Html 記得加入 <br /> <meta http-equiv="content-type" content="text/html;charset=Big5" /><br /><br />大概就這樣吧,我抱著參觀懷舊的心情來寫這個網頁 XD<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8426848800027779300?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-84821023682862939112008-03-20T11:56:00.002+08:002008-03-20T12:10:45.271+08:00Rails 2.0 比起 Rails 1.2 加速不少好像是一個對岸人赖洪礼 在自己 blog 發表一篇<a href="http://izumi.plan99.net/blog/index.php/2008/03/18/performance-comparison-rails-126-vs-202/">壓力測試</a>。他發現到 Rails 2.0 比起 Rails 1.2 加速不少,大概是 30%~50%。不過,他的測試方式相當的原始,用 ab 去量 scaffold 頁面的 req/sec。所以數字比例根本不能做准。<br /><br />但是,至少說明 Rails Team 有在為了 performance 盡力,並且有實際的成果。<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-8482102368286293911?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-46512398972652491602008-03-15T12:11:00.001+08:002008-03-15T12:11:31.257+08:00Netbeans 6 相當的威<p>前陣子需要一個 IDE 來教課,需求如下</p><br /><ol><br /> <li>好安裝</li><br /><br /> <li>跟 Rails 整合良好</li><br /></ol><br /><p>就選了 Netbeans 6 來試試看,結果發現真的還蠻不錯的,因為都是 Sun 的東西,所以直接跟 jruby 有很好的整合</p><br /><ul><br /> <li>Navigation 還不錯用,可以直接跑到這個 Controller 相關的 View,或是這個 View 相關的 Controller ,也可以指到這個 Class 宣告的地方。</li><br /><br /> <li>內建 svn ,也比 Eclipse 還得裝 SubEclipse 來的方便。</li><br /><br /> <li>內建 jruby ,也可以直接包成 war file</li><br /><br /> <li>Find Usage 可以找出所有使用這個 class 的程式碼所在,主要找出所有使用這個 Model 的 Controller 列表</li><br /><br /> <li>內建 mysql GUI Tool</li><br /><br /> <li>Code Hint 超棒</li><br /></ul><br /><p>最重要的是,他可以直接把 Model 對應到 attribute 給取出來</p><br /><p><img src="http://farm4.static.flickr.com/3296/2334510284_58f6572262.jpg" width="480" height="163" alt="activerecord6.png" /></p><br /><p>Product Model 裡面有 description,image_url ... title 等 table column ,Netbeans 6 可以直接取出來放到 code hint 裡面去。這樣就省了點找 db column 的時間了。不過這個功能必須使用 migration ,或是將 db schema dump 到 schema.rb 才可以用,也就是說不是 live db connection 去取 schema 啦。</p><br /><p>Netbeans 6 最大的缺點就是速度太慢了.......,不過 6.1 Beta 已經改善了不少。大家可以試試看。</p><br /><p>不過我的話,還是 vim 無敵呀。Navigation 用 gf 可以直接跳來跳去,Find Usage 可以用 grep -r --color Patern dir 來取代, 取出 db schema 可以直接用 mysql client + explain db schema 來做到。鍵盤還是真正的王道。</p><br /><br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4651239897265249160?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-79150203546894414392008-03-09T19:18:00.005+08:002008-03-09T19:59:13.323+08:00Rails PUSH Server :Juggernaut 簡介早就想寫 Juggernaut 的文章了,不過今天是第一次有時間寫。Push Server 技術就不再提了,想知道可以看我之前寫的文章。
<br />
<br /><span style="font-size:130%;"><span style="font-weight: bold;">簡介</span></span>
<br />
<br />Juggernaut 簡單的來說,是一個 Ruby Push Server 加上 Rails Plugin。
<br />
<br />Push Server 取名就叫作 Juggernaut。
<br />
<br />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 整合良好,我們來看看怎麼使用。
<br />
<br /><span style="font-size:130%;"><span style="font-weight: bold;">安裝</span></span>
<br />
<br />1. Push Server 安裝
<br />
<br />gem i juggernaut -y
<br />
<br />2. Rails Plugin 安裝
<br />
<br />ruby script/plugin install http://juggernaut.rubyforge.org/svn/trunk/juggernaut
<br />
<br />
<br />設定
<br />
<br />1. Juggernaut_hosts.yml
<br />
<br />這裡很容易混淆,這個設定檔是 Rails Plugin 要看的設定檔,如果沒有設定 config/juggernaut_hosts.yml,會導致 Rails 無法啟動,所以必須要設定 config/juggernaut_hosts.yml。請先新增一個 config/juggernaut_hosts.yml ,輸入你的 Push Server 環境
<br />
<br />:hosts:
<br />- :port: 5001
<br />:host: localhost
<br />:environment: :production
<br />
<br />port 是 push server port ,預設是 5001,Host 是 Push Server 的 IP ,Enviroment 是 Rails 環境。
<br />
<br />2. juggernaut.yml
<br />
<br />我們用 juggernaut 來產生 juggernaut push server 所需的設定檔。以下指令會產生一個 juggernaut config 檔,取名叫作 juggernaut.yml。
<br />
<br />juggernaut -g juggernaut.yml
<br />
<br /><span style="font-size:130%;"><span style="font-weight: bold;">啟動</span>
<br /></span>
<br />要啟動就是要啟動 Push Server ,還有 Ruby on Rails 。
<br />1. 啟動 push server
<br />我們啟動 juggernaut 這個 push server,並且讀取 config 檔。 預設 Push Server port 是 5001,可以到 juggernaut.yml 去修改。
<br />juggernaut -c juggernaut.yml
<br />
<br /><span style="font-size:130%;"><span style="font-weight: bold;">範例</span>
<br /></span>
<br />我們直接用 juggernaut 的範例,聊天室來確認是否 ok。在你的 controller 裡面創立兩個 function
<br /><pre><strong>def<span style="color: rgb(255, 0, 0);"> index</span></strong>
<br /><strong>end</strong>
<br />
<br /><strong>def<span style="color: rgb(255, 0, 0);"> send_data</span></strong>
<br />render <span style="color: rgb(68, 68, 255);">:</span>juggernaut <strong>do</strong> |page|
<br />page.insert_html <span style="color: rgb(68, 68, 255);">:</span>top<span style="color: rgb(68, 68, 255);">,</span> <span style="color: rgb(0, 128, 0);">'chat_data'</span><span style="color: rgb(68, 68, 255);">,</span> <span style="color: rgb(0, 128, 0);">"<li><span style="color: rgb(32, 64, 160);">#{h params[:chat_input]}</span></li>"</span>
<br /><strong>end</strong>
<br />render <span style="color: rgb(68, 68, 255);">:</span>nothing <span style="color: rgb(68, 68, 255);">=></span> <strong>true</strong>
<br /><strong>end</strong></pre>然後在 index view 裡面這樣寫
<br /><pre><span style="color:#4444ff;"><</span>html<span style="color:#4444ff;">></span>
<br /> <span style="color:#4444ff;"><</span>head<span style="color:#4444ff;">></span>
<br /> <span style="color:#4444ff;"><</span><span style="color:#008000;">%= javascript_include_tag :defaults, :juggernaut %>
<br /> <%=</span> juggernaut %<span style="color:#4444ff;">></span>
<br /> <span style="color:#4444ff;"></</span>head<span style="color:#4444ff;">></span>
<br /> <span style="color:#4444ff;"><</span>body<span style="color:#4444ff;">></span>
<br /> <span style="color:#4444ff;"><</span><span style="color:#008000;">%= form_remote_tag( :url =</span><span style="color:#4444ff;">></span> <span style="color:#4444ff;"><strong>{</strong></span> <span style="color:#4444ff;">:</span>action <span style="color:#4444ff;">=></span> <span style="color:#4444ff;">:</span>send_data <span style="color:#4444ff;"><strong>}</strong></span><span style="color:#4444ff;">,</span> <span style="color:#4444ff;">:</span>complete <span style="color:#4444ff;">=></span> <span style="color:#008000;">"$('chat_input').value = ''"</span> <span style="color:#4444ff;"><strong>)</strong></span> %<span style="color:#4444ff;">></span>
<br /> <span style="color:#4444ff;"><</span><span style="color:#008000;">%= text_field_tag( 'chat_input', '', { :size =</span><span style="color:#4444ff;">></span> <span style="color:#ff0000;">20</span><span style="color:#4444ff;">,</span> <span style="color:#4444ff;">:</span>id <span style="color:#4444ff;">=></span> <span style="color:#008000;">'chat_input'</span><span style="color:#4444ff;"><strong>}</strong></span> <span style="color:#4444ff;"><strong>)</strong></span> %<span style="color:#4444ff;">></span>
<br /> <span style="color:#4444ff;"><</span><span style="color:#008000;">%= submit_tag "Add" %>
<br /> < /form>
<br /> < id="</font"><span style="color:#008000;">"chat_data"</span> style<span style="color:#4444ff;">=</span><span style="color:#008000;">"list-style:none"</span><span style="color:#4444ff;">></span> <span style="color:#4444ff;"></</span>ul<span style="color:#4444ff;">></span>
<br /><span style="color:#4444ff;"></</span>body<span style="color:#4444ff;">></span>
<br /><span style="color:#4444ff;"></</span>html<span style="color:#4444ff;">></span></pre>這樣聊天室就完成啦,可以試試看玩玩看。
<br />
<br />對了,這個聊天室一開始有一堆 alert message,這是 Juggernaut 預設 Development 環境下會啟動 Debug Function ,只要 config 改成 Production 就不會出現一堆 alert message。<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-7915020354689441439?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-16326652776208787972008-03-05T12:10:00.001+08:002008-03-05T12:10:37.526+08:00Ebb:又來一個的 Application Server<p>這年頭發展 Application Server 好像很有搞頭,也或許是 Rails 社群對 <a href="http://lightyror.thegiive.net/2008/01/rails-is-ghetto.html">Zed Shaw 的高調離去</a>的反撲。總之,2008 年一月出了 Thin,二月出了<span style="font-family: Arial; font-size: 14px; line-height: 25px;"><a href="http://switchpipe.org/" target="_blank" style="color: #006699; text-decoration: underline;">SwitchPipe</a>和<a href="http://swiftiply.swiftcore.org/" target="_blank" style="color: #006699; text-decoration: underline;">Swiftiply</a><span style="font-family: Helvetica; font-size: 12px; line-height: normal;">,現在又有一個 Rails App Server <a href="http://ebb.rubyforge.org/">Ebb</a> 出了,而且好像真的很有料。</span></span></p><br /><p><br /><br /><img src="http://farm4.static.flickr.com/3157/2311855018_e455b8c35c_o.jpg" width="400" height="300" alt="ebb-concurrency.jpg" /></p><br /><p>上面這張圖是 ebb 跟 Mongrel ,和 Event-Driven Mongrel,Thin 的負載程度 benckmark。我們可以發現 ebb 跟其他的 Rails App Server 根本就是不同等級的負載程度。他的 Design 架構上面比較像 Event-Driven Mongrel,差別比較大的就是他很多地方用 c 寫成。</p><br /><p><strong>安裝方式</strong></p><br /><p>gem i ebb</p><br /><p>記得先安裝 glib2。</p><br /><p><strong>跑的方式</strong></p><br /><p>ebb_rails start</p><br /><p>很熟悉的指令。</p><br /><p>測試一下好了。</p><br /><br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1632665277620878797?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-67985757455920594402008-02-28T09:37:00.000+08:002008-02-28T11:36:05.628+08:00Friends for Sale :一天一千萬 Page View 的 Rails Service<p><img src="http://farm4.static.flickr.com/3035/2296646701_e917be1c63_t.jpg" width="186" height="139" alt="app_3_7019261521_7189.gif" /></p><br /><br /><p><a href="http://www.facebook.com/apps/application.php?id=7019261521">Friends for Sale</a> 是一個在 FaceBook 上面排行前十的 Facebook App,最近他公佈他的<a href="http://highscalability.com/friends-sale-architecture-300-million-page-view-month-facebook-ror-app">資料</a>,他是 Ruby on Rails 寫的。他上面有 60萬個會員,一個月 3億個 PV,並且以每個月 300%繼續成長。上個月流量是 3T,不過大部份都是圖片的支出。<br /></p><br /><br /><p>架構是標準的 Rails Cluster,Front end 是 Nginx,Application Server 是 Mongrel。</p><br /><br /><p>他們學到課程如下</p><br /><ol><br /> <li>如果在Facebook 上面開發 APP,一開始就要想到 Scaling Problem(四周就衝到 1 m pv/day)</li><br /><br /> <li><strong>Ruby on Rails can scale</strong></li><br /><br /> <li><strong><span style="font-weight: normal;">Performance Problem 是在 DB,你需要有很好的 DBA</span></strong></li><br /><br /> <li><strong><span style="font-weight: normal;">Cache 用的好,DB 不嫌少</span></strong></li><br /></ol><br /><p>他們使用</p><br /><ol><br /> <li>Ruby on Rails</li><br /><br /> <li>CentOS 5</li><br /><br /> <li>Memcached</li><br /><br /> <li>MySQL 5.1</li><br /><br /> <li>Nginx</li><br /><br /> <li>Starling( Distribute Queue Server)<span style="color: #494949; font-family: Verdana; line-height: 20px;"><a href="http://magicmodels.rubyforge.org/magic_multi_connections/" style="color: #6C420E; text-decoration: none;"></a></span></li><br /><br /> <li><span style="color: #494949; font-family: Verdana; line-height: 20px;"><a href="http://magicmodels.rubyforge.org/magic_multi_connections/" style="color: #6C420E; text-decoration: none;">Dr. Nics Magic Multi-Connections Gem</a> ( Read Write 不同個 DB)</span></li><br /></ol><br /><p>使用硬體</p><br /><ol><br /> <li>6台 4 core 的 App Server,每台 16 Mongrel Instance,並且每台都放 4GB Memcached 。</li><br /><br /> <li>4台 DB Server,上面配備 32GB 4 core servers with 4x 15K SCSI RAID 10 disks,使用 Master-Slave,用 Multi-Connection Gem 來達成 Read Write 不同 DB。</li><br /><br /> <li>1 Starling Server</li><br /><br /> <li>1 frontend server</li><br /></ol><br /><ol><br /> <li style="list-style: none"><br /></li><br /></ol><br /><br /><br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-6798575745592059440?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-12744252805619900312008-02-28T09:04:00.001+08:002008-02-28T09:04:53.425+08:00Adobe 計畫擴展Flash 支援其他語言<p>從 <a href="http://www.javaeye.com/news/1305">JavaEye 看到的東西</a>, <span style="font-family: Arial; font-size: 14px; line-height: 25px;">Adobe CTO Kevin Lynch在 Adobe Engage 上面講說,他們預計將其他 language 帶入 Flash ,使得 Flash 不只是可以用 ActionScript,還可以使用其他的 Language。最後也只是將 Language Compile成 Flash 的 swf Bytecode。</span></p><br /><p>感覺又是一個 VM 的即將誕生。</p><br /><br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-1274425280561990031?l=lightyror.thegiive.net'/></div>thegiivehttp://www.blogger.com/profile/01571087539375805403noreply@blogger.com0tag:blogger.com,1999:blog-5166551042886235322.post-42318993191557110222008-02-19T23:31:00.003+08:002008-02-19T23:39:05.118+08:00Rice - Ruby Interface for C++ ExtensionsRice - Ruby Interface for C++ Extensions<br /><br />一年半前(天啊,有這麼早嗎?)曾經介紹過 swig, 一個專門產生各種介於 C/C++ 與其他語言 interface 的產生器。他是利用一個自訂的表示法,藉由讀取該表示法,產生出各種不同真正的 binding 程式。其中也有內建不少 STL 的 binding,所以想用 STL 的東西並不見得需要自己寫,只要叫他內部的東西出來即可。<br /><br />swig 很厲害,不過他有個麻煩。雖然說 DSL 的威力強大,但是對於想要快速上手而言,其實有時候反而會是種阻礙。另一方面,我 swig 手冊翻了翻,要把 C++ port 到 ruby 很容易,但反之不亦然,要在 C++ 中使用 ruby object, 就不是那麼方便。(雖然也許這樣做是奇怪了點...)<br /><br />所以後來我試了 Rice.<br />http://rice.rubyforge.org/<br />rice 的官方手冊也說了,rice 並不是要來取代 swig 的。swig 有他的不足,而 rice 大抵上又是模仿 boost.python 而作成的,所以兩者並不同。他自己也做過不少東西是同時使用 swig 和 rice. 不過也不能說 rice 是 ruby 版的 boost.python. 因為他的目的也不是完全模仿 boost.python.<br /><br />anyway, 之所以會想試用,是出自於找不太到良好的 C++ yaml parser. 我有看到兩個 C 版本的實作,但是真不好意思啊,個人實在不太喜歡純 C 的東西...。所以想說如果可以把 ruby 的 yaml 搬過來就太好了。以下就是測試結果:<br /><br />> sudo gem install rice<br /><br />理論上這樣安裝是最方便的。要在 C++ 裡執行 ruby, 一樣會需要 ruby.h. 一般來說,他會在 lib/ruby/1.8/your_architecture/ 裡面。在我的電腦上,他是:/opt/local/lib/ruby/1.8/i686-darwin9.1.0/<br /><br />而 rice 呢,則是在 lib/ruby/gems/1.8/gems/rice-x.y.z/, librice.a 則是在 lib/ruby/gems/1.8/gems/rice-x.y.z/rice/ 下。<br /><br />所以在我的電腦裡,g++ options 是這樣下:<br /><br />-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<br /><br />主程式大概是長這樣:<br /><br /><pre>int main(){<br /> using Rice::Hash;<br /> using Rice::protect;<br /><br /> ruby_init(); // 使用 ruby 前一定要呼叫<br /> // 設定 load path, 否則 load path 會是 []<br /> rb_eval_string("$LOAD_PATH << '/opt/local/lib/ruby/1.8'");<br /> rb_eval_string("$LOAD_PATH << '/opt/local/lib/ruby/1.8/i686-darwin9.1.0'");<br /><br /> // require yaml 進來。當然也可以用上面的方式 require. 不過之所以會這樣寫,<br /> // 是因為我不知道 load path 要怎麼直接從 rb_ function 中設定?<br /> // 否則我是覺得能用 rb_ 去跑盡量用,evil eval 不是叫假的...<br /> rb_require("yaml");<br /><br /> // protect 我猜是把所有的錯誤都轉成 rice 本身的 exception.<br /> // Hash, 則是 ruby 的 hash 在 C++ 裡的 wrapper,<br /> // 所以我是把 YAML 的讀取結果存入這份 C++ Hash 中。<br /> Hash h(protect(rb_eval_string, "YAML.load(File.read('database.yml'))"));<br /><br /> // 這邊,我要做的事只是展現如何使用這份 hash.<br /> Extractor e;<br /> e.extract(h);<br /> std::cout << std::endl;<br />}</pre><br /><br />雖然我覺得 doxygen 生出來的東西常常很難閱讀,不過 rice 的 doxygen 文件還算不錯,有什麼東西都很清楚。就算不夠清楚,也能去直接看他的原始檔。他原始檔的東西並不多,稍微翻一下,有什麼疑惑我想都可以解決。根據我 C++ 的經驗,rice 這份程式也算是寫得非常漂亮的了,應該滿有參考價值。<br /><br />我的 extractor 是把整個 hash 都走過一次,如果不需要這麼複雜的操作,其實也可以很單純地這樣呼叫:<br /><br />std::cout << static_cast<Hash>(h[String("development")])[String("adapter")];<br /><br />這樣會輸出:<br /><br />sqlite1<br /><br />這樣實在是有點囉唆沒錯,不過我想這可以靠擴充 rice 解決。他有個 from_ruby 和 to_ruby 的 template, 擴充那個東西,好像就能把很多東西從 explicit 法轉成 implicit 法。不過我暫時懶得去做那麼多研究,這應該都是小問題。不過 down cast 就比較麻煩了。他有個 get method, 好像是能做一些 down cast, 但我測試都會有 runtime error, 大概是用法不對吧。有興趣的人歡迎去研究看看要怎麼做。<br /><br />extractor 我想就不解釋了,就只是單純把抓出的 yaml 再輸出回 yaml. 其實那都已經差不多單純是 C++ 的問題了。僅列出程式碼與附註的一些註解:(不過我沒測試過比較複雜的 yaml, 我想一定會有問題,當作業自己試著改好吧 :p)<br /><br /><pre>#include <ruby.h><br />#include <rice/Hash.hpp><br />#include <rice/Array.hpp><br />#include <iostream><br /><br />using Rice::Object;<br />using Rice::Class;<br />using Rice::Hash;<br />using Rice::Array;<br />using Rice::String;<br /><br />// 排版算空格用的<br />std::string spacer(int depth){<br /> std::string result;<br /> for(int i=0; i<depth; ++i)<br /> result += " ";<br /> return result;<br />}<br /><br />class Extractor{<br />public:<br /> // 他 class 判斷法有點麻煩,所以我先把這三個 class instance cache 起來<br /> Extractor(): hash_class_(Hash().class_of()),<br /> array_class_(Array().class_of()),<br /> string_class_(String().class_of())<br /> {}<br /> void extract(Object const& obj, int depth = 0) const{<br /> if(obj.is_instance_of(hash_class_))<br /> extract_hash(obj, depth);<br /> else if(obj.is_instance_of(array_class_))<br /> extract_array(obj, depth);<br /> else if(obj.is_instance_of(string_class_))<br /> std::cout << spacer(depth) << obj << "\n";<br /> else // 這表示他是 Fixnum or Float?<br /> std::cout << spacer(depth) << obj << "\n";<br /> }<br />private:<br /> void extract_array(Array const& obj, int depth) const{<br /> for(Array::const_iterator i=obj.begin(), iend=obj.end(); i!=iend; ++i)<br /> extract(*i, depth);<br /> }<br /> void extract_hash(Hash const& obj, int depth) const{<br /> for(Hash::const_iterator i=obj.begin(), iend=obj.end(); i!=iend; ++i){<br /> std::cout << spacer(depth) << i->key << ":";<br /><br /> // i->value 結果會是 ruby 上 C 的 VALUE, 所以要 cast 成 Rice::Object<br /> if(static_cast<Object>(i->value).is_instance_of(hash_class_))<br /> std::cout << "\n", extract(i->value, depth+1);<br /> else // 單純的值<br /> std::cout << " ", extract(i->value, 0);<br /> }<br /> }<br />private:<br /> Class hash_class_, array_class_, string_class_;<br />};</pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5166551042886235322-4231899319155711022?l=lightyror.thegiive.net'/></div>godfat 真常http://www.blogger.com/profile/04471393622959484230noreply@blogger.com0