前の投稿でSinatraはRubyそのものでDSLじゃないと言いました。
SinatraはDSLなんかじゃない、Ruby偽装を使ったマインドコントロールだ!
確かに内部DSLというのはそういうものなのかもしれません。でも言語といったら独自の構文くらいはもっていたい。それで、コードをそのままRubyに通したら、Syntaxエラーになってほしい。
ちょっと意味不明ですけど...
そんなわけで...
独自構文を持つSinatra、Chinatra を作りました ^ ^;1 (ネタ注意!)
#myroute.rb
get /
haml :index
get /hi
'hi, my friend!'
get /:name
hello(params[:name])
helpers
- hello(name)
"Wow you are #{name}!" -
独自の構文です!これはそのままRubyには通りません。
以下のファイルを用意します。
#app.rb
require_relative 'chinatra'
require 'myroute'
chinatraライブラリをrequireして さらに先のmyroute.rbをrequireします そしてこのapp.rbをrubyで実行します
$ ruby app.rb
== Sinatra/1.2.6 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.2.11 codename Bat-Shit Crazy)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:4567, CTRL+C to stop
image
独自構文のSinatraができました!
関連記事:内部DSLを使って、RubyのWebフレームワークを書こう!
require "sinatra"
module Chinatra
class Application
SINATRA_METHODS = Sinatra::Delegator.private_instance_methods(false)
def self.parse(fname)
file = open(fname) rescue open("#{fname}.rb")
code = file.lines.inject([]) do |mem, line|
case line
when /^(#{SINATRA_METHODS.join('|')})\s*(.*)\s*$/
mem << "};" << %[ #{1ドル}("#{2ドル}") { ]
when /^\s+-\s+(.*)$/
mem << 'def ' + 1ドル
when /^\s+(.*)\s+(-)$/
mem << 1ドル + ' end'
else
mem << line + ';'
end
end
eval code.rotate.join
end
end
end
module Kernel
alias :_require :require
def require(feature)
_require feature
rescue LoadError
Chinatra::Application.parse(feature)
end
end
at_exit { Sinatra::Application.run! }
.rbさえつけなければとてもいいと思います! > tkawaさん
ありがとうございます!.rbのところちょっとだけ直しました。