Waves のチュートリアル Compact Apps をやってみる
リソース指向というのを体験してみるため、Waves のオフィシャルサイトに乗っている Getting Started: Compact Apps をやってみたいと思います。
※以下、まだメモ書きなので日本語がこなれていません。
アプリケーションの雛形を作成
他のフレームワーク同様に、アプリケーションの雛形を作成する waves コマンドがあります。これで、雛形を作成します。
$ waves generate --name=spit_ball --template=compact ** Waves 0.8.2 ** ** Creating new Waves application ... ** Application created!
waves の generate コマンドで spit_ball という名前のアプリケーションを compact テンプレートを使って作成しました。
waves コマンドの実行でエラーが発生した場合は、Ubuntu 8.10 に Waves をインストール を参考に追加インストールしてみて下さい。
テンプレートとして指定した compact っていうのは、画面のテンプレートではなく、作成するアプリケーションのテンプレートになるようです。compact と classic を指定できるのですが、compact を指定すると動作に必要なたった一つの雛形ファイルが作成されます。classic を指定すると Rails のように MVC スタイルのファイルがたくさん作成されるようです。
waves コマンドのオプションとして、利用する ORM も指定できます。詳しくは waves --help で。
出来上がったファイルを見てみると、spit_ball というディレクトリに startup.rb というファイルが作成されていました。
中身はこんな感じです。
startup.rb
require 'foundations/compact' module SpitBall include Waves::Foundations::Compact end
まさにコンパクト。さてこれを実行してみたいと思います。
$ cd spit_ball $ waves server ** Waves 0.8.2 ** I, [2008-12-23 13:44:11 #16704] INFO -- : Logger started. I, [2008-12-23 13:44:11 #16704] INFO -- : Waves::Server starting ... no such file to load -- ruby-debug
動かんではないか!ということで、sudo gem install ruby-debug して再実行すると、
$ waves server ** Waves 0.8.2 ** I, [2008-12-23 13:49:49 #16971] INFO -- : Logger started. I, [2008-12-23 13:49:49 #16971] INFO -- : Waves::Server starting ... I, [2008-12-23 13:49:49 #16971] INFO -- : ruby-debug enabled I, [2008-12-23 13:49:50 #16971] INFO -- : Mongrel started on 127.0.0.1:3000.
無事に起動しました。
まずはこの状態で http://localhost:3000/ にアクセスしてみると、あずき色の背景に 404 Not Found と表示されます。
アプリケーションのレイヤー
Waves で作るアプリケーションは、モジュールの Mixin を使った階層化構造になっているらしい。と言う解説が書いてあった。ここはサラッと流して次にすすんでみた。そのうちわかるだろう。
リソース
Waves にとってリソースはスパルタの戦士らしい。強そうだ。他のクラスはこのリソースの奴隷なんだそうだ。強いにちがいない。
ということで、リソースを追加してみる。もともとあった startup.rb に module Resources と class Map を追加する。
startup.rb
require 'foundations/compact'
module SpitBall
include Waves::Foundations::Compact
module Resources
class Map
on(:get) { "Hello World!" }
end
end
endSpitBall::Resources::Map クラスはアプリケーションのエントリーポイントになるそうです。みたまんま、HTTP GET のときに "Hello World!" を返すということで、waves server して http://localhost:3000/ すると Hello World! と表示された。
このままでは waves server コマンドはコードのリロードをしないそうなので、CTL+C してからもう一回 waves server する必要があるそうです。
Map クラスの on メソッドをもうちょっと詳しく理解するために、2 行追加します。
startup.rb
require 'foundations/compact'
module SpitBall
include Waves::Foundations::Compact
module Resources
class Map
on(:get) { "Hello World!" }
on(:get, ['hello']) { "こんにちは!" }
on(:get, ['hello', :name]) { "Hello, #{captured.name}!" }
end
end
endon メソッドの指定 |
URL |
表示される文字列 |
on(:get) |
Hello World! |
|
on(:get, ['hello']) |
こんにちは! |
|
on(:get, ['hello', :name]) |
Hello, パラメータ! |
ということで、on メソッドの 2 番目の引数には URL のパスにマッチするように Rails とかでいうルーティングの指定をするようです。
こういう場合に重要となってくる on メソッドの指定順序ですが、同じような on があった場合、後ろの方に書いた on メソッドが前の on を上書きするそうです。なので、
startup.rb
require 'foundations/compact'
module SpitBall
include Waves::Foundations::Compact
module Resources
class Map
on(:get) { "Hello World!" }
on(:get, ['hello', 'japanese']) { "こんにちは!" }
on(:get, ['hello', :name]) { "Hello, #{captured.name}!" }
end
end
endこうすると、on(:get, ['hello', :name]) が on(:get, ['hello', 'japanese']) を上書きすることになるので、ブラウザに 'こんにちは!' と表示されることはないのですね。
コードのリロードとリソースの委譲
コードを変更するたびに waves server を再起動しなくてはいけませんでしたが、自動でコードを再読み込みするようにすることができます。それから、リソースの委譲について。
startup.rb を書き換えて、新しく greeting.rb ファイルを作成します。
startup.rb
require 'foundations/compact'
require 'autocode'
module SpitBall
include Waves::Foundations::Compact
module Resources
include AutoCode
auto_load true, :directories => '.'
class Map
on(true) { to(:greeting) }
end
end
module Configurations
class Development
reloadable [Resources]
end
end
endgreeting.rb
module SpitBall
module Resources
class Greeting
include Waves::Resources::Mixin
on(:get) { "Hello World!" }
on(:get, ['hello']) { "こんにちは!" }
on(:get, ['hello', :name]) { "Hello, #{captured.name}!" }
end
end
end先に書いてあった、モジュールを積み重ねて Mixin してといったあたりがだんだん見えてきました。
まずは require 'autocode' で有効になった AutoCode を SpitBall::Resources で include しています。その他もろもろのメソッド指定によって、SpitBall::Resources モジュール内のクラス Greeting が必要なときに greeting.rb を動的にロードするようになっています。
クラス名とファイル名の関連は snake-case (っていうんですね) を使って、たとえば BlogPost というクラスは blog_post という名前に変換してファイルをロードするそうです。
そして、SpitBall::Configurations::Development の reloadable [Resources] で、見たまんまですが、開発時は SpitBall::Resources モジュール内のクラスをリロードできるようにしています。こうすることで、SpitBall::Resources モジュール内のファイルを変更した際に waves server がファイルを自動的にリロードするようになります。いちいちサーバーを再起動しなくてもよくなるってことですね。
それから、さっきまでいじっていた on に true を指定すると、この on がすべてのリクエストをハンドリングするようになります。ブロック指定で to(:greeting) することで、SpitBall::Resources::Greeting へリクエストを委譲するようになります。そしてこの、SpitBall::Resources::Greeting は、AutoLoad によって自動で読み込まれるということで。なるほど。
まだまだ続きます...
Waves - Ruby の WEB アプリケーションフレームワーク