昨日Railsワークショップ@新橋に参加しました。
Ruby の新しいフレームワークで Rails よりも軽くて早いという Waves を、チュートリアルに沿いながら動かそうとしてみたのですが、いきなり大いにはまりました。しかし「乗りかけた船」だったので、頑張ってなんとか動かすところまではこぎつけました。
» Ruby Waves: Home
» Ruby Waves: Tutorial, Part 1
インストールは簡単。
% sudo gem install waves
で入りますが、ずらずらっと10以上の依存しているパッケージがインストールされました。
で、しょっぱなの
% rake schema:migration name=initial_schema
のところで
Could not load mysql adapter:
no such file to load -- mysql
というエラーが出て、いきなりつまずきました。
調べたら、どうやら gem の mysql パッケージがインストールされていることが前提であることがわかりました。
ところが、Mac OS X Leopard だと、
% sudo gem install mysql
とやっても
ERROR: While executing gem ... (Gem::Installer::ExtensionBuildError)
ERROR: Failed to build gem native extension.
というエラーが表示され、インストールできないのです。
しばしはまるのですが、結局
» Nullcreations | Installing ruby mysql gem in OSX 10.5 (Leopard)
にあった解決法でうまくいきました。
% sudo su
% ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-dir=/usr/local/mysql
% install_name_tool -change /usr/local/mysql/lib/mysql/libmysqlclient.15.dylib /usr/local/mysql/lib/libmysqlclient.15.dylib /Library/Ruby/Gems/1.8/gems/mysql-2.7/lib/mysql.bundle
これで無事マイグレーションファイルを作成することができ、その後は順調にチュートリアルを進めることができました。
以下チュートリアルをやってみた感想です。
- Controller と Model のコードをなかなかいじらない。つまり何も書かなくてもある程度のことができてしまうところが Rails と違う。
- generator が Rake タスクであるところが、なんとなく美しいと思った。こういうタスクっぽいものは Rake から、と覚えておけば済むので、覚えることが少ない。
- REST の概念に慣れてないととっつきにくいかも。
- view がわかりにくい。チュートリアルでは Markaby というテンプレートを使用しているが、うーん、僕はちょっととっつきにくいかな、と感じました。これはデザイナとの協業に苦労しそう。
- チュートリアル3の最後の方、@comments.map{ |c| c }.sort_by( &:created_on ).each do |comment| の .map{ |c| c } の部分が汚い、というかよくわからない。Sequel’s MySQL adapter の Limitation らしい。
- エラーが発生したときに表示されるデバッグ用画面が Rails より綺麗。
- チュートリアルでは jQuery を使っている。Rails のような Prototype.js との密な連携がまだ見られないが、連携するとしたらたぶん jQuery だろうことが予想される。jQuery はまだあまり詳しくはないのだけど、まわりの評判は Prototype.js よりも良いので、まあこれはいいことなのであろう。
まだできたてホヤホヤ。当然 Rails の方がはるかに完成されたフレームワークなので、いますぐ移行しようとは思わない。しかし、こうして新しいフレームワークに触れてみると、いままで「Rails すばらし過ぎる。Rails 以上のフレームワークなんて作るの無理だろう。欠点なんてみつけられない」と少なからず思っていたのが、「いやいやそうでもない。Rails にもまだまだ改善できそうな点がある」という、まあこれが正常な状態だと思いますが、そういう思考に戻されました。
気になるパフォーマンスですが、apache 付属のベンチマーク測定ツール apache bench を使って Rails の方は mongrel と比較してみました。Rails の方は Waves のチュートリアルで作ったものとほぼ同じようなテストアプリを作成して比較しています。
% ab -c 10 -n 1000 http://127.0.0.1:3000/entries
waves の結果が
Requests per second: 23.97 [#/sec] (mean)
Time per request: 417.104 [ms] (mean)
Time per request: 41.710 [ms] (mean, across all concurrent requests)
Transfer rate: 21.27 [Kbytes/sec] received
mongrel が
Requests per second: 8.70 [#/sec] (mean)
Time per request: 1148.924 [ms] (mean)
Time per request: 114.892 [ms] (mean, across all concurrent requests)
Transfer rate: 11.65 [Kbytes/sec] received
でした。
Requests per second が約 2.7 倍。
サーバーを動かしている同じマシンから測定しているのでちゃんと測定とは言えないですし、非常に簡単な構成ですから一概には言えないと思いますが、実際にブラウザで操作している感触でも、確かに waves の方がサクサク動く感じがしました。
せっかくなので、もう一つはまりどころを情報共有しておきます。
ベンチマークを計るときに waves server をデーモンで起動しようと、
% waves-server -d
と実行したところ、
/Library/Ruby/Gems/1.8/gems/waves-0.7.2/lib/runtime/server.rb:32:in `daemonize': uninitialized constant Waves::Server::Daemonize (NameError)
というエラーが出ました。
mongrel のデーモン起動のところの似たような処理の部分を参考にして、/Library/Ruby/Gems/1.8/gems/waves-0.7.2/lib/runtime/server.rb の31行目に以下の通り require 文を追加。
30 def daemonize
31 require 'daemons/daemonize' #この部分を追加
32 pwd = Dir.pwd
33 Daemonize.daemonize( Waves::Logger.output )
あと、アプリケーションのトップフォルダ直下に
% mkdir log
で log ディレクトリを作っておきます。
これで無事デーモンで起動できるようになりました。