PerlerのRuby日記

Rubyとか

Sinatraでrake routes

SinatraRailsのroutesタスクを作ってみた。

Sinatraのバージョンは 1.4.3 で確認。

見た目重視。


トップレベルにルーティングを定義している場合

desc 'something like rake routes of Rails'
task 'routes' do
  require "./app"
  Sinatra::Application.class_eval do
    routes = self.instance_variable_get(:@routes)
    routes.each do |verb, signatures|
      next if verb == "HEAD"
      signatures.each do |signature|
        path = signature[0].to_s
        path.sub!(/^\(\?-mix:(\\A)?\\/, '')
        path.sub!(/(\\z)?\)$/, '')
        puts "%-6s %s" % [verb, path]
      end
    end
  end
end

getを定義するとheadも同時に定義するようになっていたので、そこは省いた。

出力はこんな感じ。

  • app.rb
require 'sinatra'

get '/' do end
get '/hello' do end
post '/hello' do end
put '/hello' do end
delete '/hello' do end

get '/hello/:name' do
  "Hello #{params[:name]}!"
end

get '/say/*/to/*' do
  params[:splat]
end

get %r{/hello/([\w]+)} do
  "Hello, #{params[:captures].first}!"
end
$ bundle exec rake routes
GET    /
GET    /hello
GET    /hello\/([^\/?#]+)
GET    /say\/(.*?)\/to\/(.*?)
GET    /hello\/([\w]+)
POST   /hello
PUT    /hello
DELETE /hello

Sinatra::Baseを継承している場合

本格的なアプリ作るときはこちらの方が多いとおもう。

desc 'something like rake routes of Rails'
task 'routes' do
  require "./app"
  #Sinatra::Application.class_eval do
  Myapp.class_eval do
    routes = self.instance_variable_get(:@routes)
    routes.each do |verb, signatures|
      next if verb == "HEAD"
      signatures.each do |signature|
        path = signature[0].to_s
        path.sub!(/^\(\?-mix:(\\A)?\\/, '')
        path.sub!(/(\\z)?\)$/, '')
        puts "%-6s %s" % [verb, path]
      end
    end
  end
end
  • app.rb
require 'sinatra/base'

class Myapp < Sinatra::Base
  get '/' do end
  get '/hello' do end
  post '/hello' do end
  put '/hello' do end
  delete '/hello' do end

  get '/hello/:name' do
    "Hello #{params[:name]}!"
  end

  get '/say/*/to/*' do
    params[:splat]
  end

  get %r{/hello/([\w]+)} do
    "Hello, #{params[:captures].first}!"
  end
end
$ bundle exec rake routes
GET    /
GET    /hello
GET    /hello\/([^\/?#]+)
GET    /say\/(.*?)\/to\/(.*?)
GET    /hello\/([\w]+)
POST   /hello
PUT    /hello
DELETE /hello

ただでさえルーティングとコントローラの処理を一緒に書いてごちゃごちゃしがちなので

ルーティングだけでも綺麗に見たかった。


Railsのそれと違って、書いた順に並べられなかったのがちょっと残念。