Ruby言語やLinuxのネタが多いです。
February 26, 2009 [おもひで]
■ [Rails] Rack-0.9.1を試す
早くもlocale_railsがRails-2.3.0rc1で動作しなくなった。
Rack統合が原因であることはすぐにわかった(ActionController::AbstractRequestがなくなったことでエラーになっていた)が、そもそもRackって何ぞや、ということで試してみることにした。
こちらを参考に。
まずはインストール
gem install rack
hello.rb
require 'rubygems'
require 'rack'
class HelloApp
def call(env)
body = "Hello, Rack"
[200, {"Content-Type" => "text/plain"}, [body]]
end
end
hello.ru
require 'hello' run HelloApp.new
サーバ起動
$ rackup hello.ru
Firefoxからhttp://localhost:9292/ にアクセスして・・・ NO!! ほぼコピペなのにエラー・・・orz。
Rack::Lint::LintError: No Content-Length header found
このバージョンではContent-Lengthを指定しないといけないのか・・・。なるほど。
require 'rubygems'
require 'rack'
class HelloApp
def call(env)
body = "Hello, Rack"
[200, {"Content-Type" => "text/plain", "Content-Length" => body.length}, [body]]
end
end
サーバ再起動。うーん、またしてもエラー。
Rack::Lint::LintError: header values must respond to #each, but the value of 'Content-Length' doesn't (is Fixnum)
#each持ってないといけないのか・・・・。Fixnumじゃダメってことなのね。とりあえず配列にしてみよう。
require 'rubygems'
require 'rack'
class HelloApp
def call(env)
body = "Hello, Rack"
[200, {"Content-Type" => "text/plain", "Content-Length" => [body.length]}, [body]]
end
end
サーバ再起動。うーん、またしてもエラー。
Rack::Lint::LintError: header values must consist of Strings, but 'Content-Length' also contains a Fixnum
文字列じゃないとダメってことか?
require 'rubygems'
require 'rack'
class HelloApp
def call(env)
body = "Hello, Rack"
[200, {"Content-Type" => "text/plain", "Content-Length" => body.length.to_s}, [body]]
end
end
"Hello, Rack" やったーっ!(ヒーローズのヒロ風。勢いで牡丹をジンタンと読む感じで)
.... ってか、疲れた。locale_railsはまた後にしよう。
■ [Rails] Rack-0.9.1 + Ruby-Locale-0.9.0
LocaleのCGIドライバは、Ruby標準添付のCGIモジュールに依存した作りになっているのだが、CGIを使わずにRack::Requestを使用するRackではそのままではRuby-Localeを使えない。で、ちょっとだけRack::RequestをいじってCGIと同じように振る舞うようにしてしまうことでRuby-Localeで動作するようになる。
require 'rubygems'
require 'rack'
require 'locale'
module Rack
class Request
def has_key?(key); params.has_key?(key); end
def accept_language; env["HTTP_ACCEPT_LANGUAGE"]; end
def accept_charset; env["HTTP_ACCEPT_CHARSET"]; end
end
end
class HelloApp
Locale.init(:driver => :cgi)
def call(env)
request = Rack::Request.new(env)
Locale.set_cgi(request)
str = "#{Locale.candidates.inspect}"
[200, {"Content-Type" => "text/plain", "Content-Length" => str.length.to_s}, [str]]
end
end
ちなみにRails-2.3.0の新しいActionController::RequestはRack::Requestを継承しつつ、CGIに近いインタフェースになっているのでLocaleのCGIドライバをそのまま使える・・・といいのだけど・・・。has_key?は無さげだ・・・orz。
