Moneta: 提供 key/value stores 的統一介面

今天我想特別介紹這一套 Ruby library: Moneta

它提供了 key-value stores 標準共通的使用介面,讓你可以用相同的程式,但是可以輕易轉換底層實際使用的儲存庫,包括:

  • Basic File Store
  • BerkeleyDB
  • CouchDB
  • DataMapper
  • File store for xattr
  • In-memory store
  • Memcache store
  • Redis
  • S3
  • SDBM
  • Tokyo
  • Xattrs in a file system

它的用法其實跟 Hash API 差不多,非常容易使用。我認為最實際的用途是用在撰寫快取程式了。

因為不同環境可以輕易切換 store 的這個好處,我在 local 的 development 環境中,可以使用 In-memory store 或 File Store (前者重開 server 快取資料就會消失,後者則會留著),不需要多裝東西就可以寫快取。更重要的是,團隊中其他人也不需要費心設定 (叫每個人都去裝 Memcached 也太辛苦了)。而在 production 正式環境中,則可以輕易設定成使用 Memcached

我自己也用了 Moneta 介面寫了一個小程式 Headcache,提供了 get_and_set 功能:


data = Handcache.get_and_set("data-123", :expires_in => 60 ) do
                "cached-foobar"
            end

如果快取存在,就回傳快取資料;如果不存在,就執行 code block,並將最後的運算值回傳並快取起來。

如果是在 View 中搭配 partial 使用也非常簡單:


<%= Handcache.get_and_set( dom_id(@post), :expires_in => 60 ) do
               render :partial => "post"
           end %>

設定的方法則可以是:


# config/environments/development.rb
begin
  # for developer has tokyo cabinet
  Handcache = Moneta::Tyrant.new( :host => 'localhost', :port => 1978 )
rescue
  # for developer has not tokyo cabinet
  Handcache = Moneta::BasicFile.new( :path => "tmp" )
end

關於快取這件事情的學問,可以參考我之前的 Memcached 文章:一是如何清除過期的快取資料(expire),二是注意快取 Key 的命名。

Rails Best Practices Gem: 靜態分析Rails程式碼

Rails Best Practices Gemflyerhzm 根據我的 Rails Best Practices 演講的內容,所作出來的靜態分析程式,可以幫助你快速找到一些可能可以改善的地方。

透過 sudo gem install rails_best_practices –source gemcutter.org 安裝之後,只要執行 rails_best_practices . 就會開始分析你的程式,十分神奇。

這個 gem 也被 Ruby5 – Episode #28Rails Envy Podcast – Episode 102InfoQ China 等介紹。

校園自由工作坊-Ruby 初探 @ 清華大學資工系

Update (2010/12/3): 本活動 12/7 才會開放報名。

又要開課了,和上一回類似的課程內容,這次 OSSF 和清大資工系合辦,時間地點是 12/23 在清華大學 :)

這次真的是大學生了,準備來把範例改成瞇圖程式(?)
anyway,能夠回母校上點課,真是開心 :)

Why “Not use default route”?

In my Rails Best Practices slides, I only give simple code without any description (unless you heard my talk :p), so let me explain here.

my point is: “If you use RESTful design, you should NOT use default route.” Why?

For example:


map.resources :users
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'

You expect only “PUT /users/1” will update user data, but because you keep default route, so “GET /users/update/1?user[email]=[email protected]” still works!!

In the same way, “GET /users/create” and “GET /users/destroy/1” works too!! Even worse, the latter can create/update/destroy data without Request Forgery Protection :/ Rails does not check CRSF for HTTP GET.

Conclusion: Remove default route, use purely resource-based routes and named routes for special purpose.