内部DSLを使って、RubyのWebフレームワークを書こう!
Sinatraのようなベース言語の構文を使って実現するDSLを内部DSLといいます。前回僕が書いたChinatraは一見内部DSLにみえるけど、ベース言語とは異なる構文を使った外部DSLです。
でも時代の風は内部DSLに向いています。
自分もRubyの構文のユルさとメタプログラミングを使ってSinatraのような内部DSLを書いてみたい。
そしてRubyistをマインドコントロールしたい..
そんなわけで…
Sinatraと別の構文を持ったWebフレームワーク「Shynatra」をRubyで書きました:-)
ShynatraはRubyで下記のような最小労力で、手早くウェブアプリケーションを作成するためのDSLです。
# myapp.rb
require "shynatra"
R/:hello./ {
'Hello world!'
}
R はCRUDのRです。/:hello
の部分はパス(/hello)になります。先頭のコロンはパラメータを表しているわけではありません。./
はパスの終端子です。気に入らなくても省略はできません。それでも気に入らない人は.|
か ._
を使いましょう。
Rubyに慣れていない方のために一言付け加えますが、これはよく使われる由緒正しきRubyの構文です..解説はこちら1。
ルートパスの指定にはnilを使います。
R/nil./ {
@message = message "Shynatra"
haml :index
}
H/nil./ {
def message(app)
"Welcome to #{app}!"
end
}
SinatraのHelpersに対応するのはHです。Hを使うときも無意味に/nil./
します
ええ、nilするんです。
パスの区切りは_(アンダースコア)を使います。つまり/foo/bar
は以下のように指定します。
R/:foo_bar./ {
"You are in: '/foo/bar'"
}
当然、パス名にアンダースコアを含めることはできません。
名前付きパラメータは@
を前置します。
R/:@name./ {
"Hello, " + params[:name]
}
この場合もコロンは必須です。忘れてはいけません。
名前付きパラメータをルート以外で使いたいこともあるでしょう。そのときは6を使います。
R/:foo_6name./ {
"You are in: '/foo/:name' with '#{params[:name]}'"
}
R/:foo_6bar_baz_6name./ {
"You are in '/foo/:bar/baz/:name' with :bar => #{params[:bar]}, :name => #{params[:name]}"
}
ええ、数字の6です。冗談じゃなく。
解説は以上です。CRUDのC U D も多分動くと思います。詳細はコードを見てくださいね。
Rubyの内部DSLであなたも**natraしてみませんか?
関連記事:
- R./(Rクラスのクラスメソッド/)を引数付きで呼んでいる。引数には、:hello#/(シンボル:helloのインスタンスメソッド/)をブロック付きで呼んだ返り値が渡される ↩
blog comments powered by Disqus