ayuminのあまり更新しないBlog

筆不精なのでめったに更新しません

品虎

品虎 - Sinatra は超お手軽に使えるWebアプリケーションフレームワークで、結構お気に入りです。
社内のRuby勉強会でもこれからはなるべく動くコードをどんどん作っていきたいのだけれど、Railsはなんつーか覚えることが多すぎたりよく分からない部分が多いのでとりあえず成功体験を与えるためにSinatra + Erbの組み合わせで何か作っていこうかと思った。

で、念のため最新のSinatraでhello, world 的なモノを作ったのだが・・・ナント、サーバーが立ち上がらない。
前はうまくいったはずなんだけどなぁ〜と思って調べてみた。

ayumin@ubuntu:~/work$ gem list | grep sinatra
sinatra (0.9.2)

品虎のバージョンは0.9.2

ayumin@ubuntu:~/work$ ruby myapp.rb
/var/lib/gems/1.8/gems/sinatra-0.9.2/lib/sinatra/base.rb:931:in `detect_rack_handler': Server handler (thin,mongrel,webrick) not found. (RuntimeError)
        from /var/lib/gems/1.8/gems/sinatra-0.9.2/lib/sinatra/base.rb:862:in `run!'
        from /var/lib/gems/1.8/gems/sinatra-0.9.2/lib/sinatra/main.rb:34
        from myapp.rb:6

こんなふうになる。で、sinatra/base.rbの931行目をみる。

    # File lib/sinatra/base.rb, line 922
922:      def detect_rack_handler
923:        servers = Array(self.server)
924:        servers.each do |server_name|
925:          begin
926:            return Rack::Handler.get(server_name.capitalize)
927:          rescue LoadError
928:          rescue NameError
929:          end
930:        end
931:        fail "Server handler (#{servers.join(',')}) not found."
932:      end

このあたりです。コンソールに出ていたエラーメッセージ"Server handler (thin,mongrel,webrick) not found. "が931行目から出力されているのがわかる。で、ちょっと上をみてみると、924行目のeachブロックでRack::Handlerを取得している。結局ここで失敗しているから931行目が実行されるので、Rack::Handler.getを調べてみる。

Rackについてもっと詳しく調べたいひとはこちらをご覧ください

    # File lib/rack/handler.rb, line 11
11:    def self.get(server)
12:      return unless server
13:      server = server.to_s
14:
15:      if klass = @handlers[server]
16:        obj = Object
17:        klass.split("::").each { |x| obj = obj.const_get(x) }
18:        obj
19:      else
20:        try_require('rack/handler', server)
21:        const_get(server)
22:      end
23:    end

よくわからないケド、品虎の方でサーバー名を勝手にcapitalizeしているからgetに失敗しているのではないかと思ったので、ちょと改造して実験。

    # File lib/sinatra/base.rb, line 922
922:      def detect_rack_handler
923:        servers = Array(self.server)
924:        servers.each do |server_name|
925:          begin
926:            return Rack::Handler.get(server_name)
926:            # return Rack::Handler.get(server_name.capitalize)
928:          rescue LoadError
929:          rescue NameError
930:          end
931:        end
932:        fail "Server handler (#{servers.join(',')}) not found."
933:      end
ayumin@ubuntu:~/work$ ruby myapp.rb
== Sinatra/0.9.2 has taken the stage on 4567 for development with backup from WEBrick
[2009-06-24 03:32:41] INFO  WEBrick 1.3.1
[2009-06-24 03:32:41] INFO  ruby 1.8.7 (2008-08-11) [i486-linux]
[2009-06-24 03:32:41] INFO  WEBrick::HTTPServer#start: pid=22962 port=4567

どうやらうまくいった。
sinatra本体を改造するのに気が引ける場合はcapitalizeされた"Webrick"という文字列とWEBrickをRackでマッピングできるように、おまじないを入れておけばいい。

require 'rubygems'
require 'sinatra'

Rack::Handler.register 'Webrick', 'Rack::Handler::WEBrick' # おまじない

get '/' do
  'Hello, world!'
end