GAE/JRuby/Sinatra でサービスを作ってみるテスト (2)

くっそー、ハマった。
タダだべを GAE に移植するには、要するに「メールで遠隔操作するブラウザ」を作ればいいわけで、Ruby Mechanize を GAE 上で動かすとこまでは OK*1。セッションをまたいでリンクをたどるためには履歴と付加情報 (リファラとかクッキーとか) が必要なので、いっそ Mechanize オブジェクトを丸ごとデータストアに突っ込んで再利用してやろうと…

require "mechanize"
require "dm-core"

class BrowserData
	include DataMapper::Resource
	property :id, Serial
	property :username, String, :required => true, :unique => true
	property :agent, Object, :required => true
end

class Browser
	def initialize(username)
		@username = username
		@browserdata = BrowserData.first_or_create(
			{ :username => username },
			{ :agent => WWW::Mechanize.new }
		)
		@agent = @browserdata.agent
	end
end

…したら…

TypeError - can't dump hash with default proc:
 file:/home/www/appengine1@gae/toybox3/WEB-INF/lib/gems.jar!/bundler_gems/jruby/1.8/gems/dm-core-1.0.2/lib/dm-core/property/object.rb:13:in `dump'
(中略)
 file:/home/www/appengine1@gae/toybox3/WEB-INF/lib/gems.jar!/bundler_gems/jruby/1.8/gems/dm-core-1.0.2/lib/dm-core/model.rb:446:in `first_or_create'
 /home/www/appengine1@gae/toybox3/models/browser.rb:19:in `initialize'

…えっ? も、もしや…

デフォルトオブジェクトが Proc である Hash は dump できない

h = Hash.new { }
Marshal.dump(h)
=> -:2:in `dump': cannot dump hash with default proc (TypeError)
http://www.ruby-lang.org/ja/man/html/Marshal_A5D5A5A9A1BCA5DEA5C3A5C8.html

ナンダッテー (´Д`;
ちょっと調べたところ、怪しいのは www/mechanize.rb の 139 行目。

      @scheme_handlers  = Hash.new { |h,k|
        h[k] = lambda { |link, page|
          raise UnsupportedSchemeError.new(k)
        }
      }
      @scheme_handlers['http']      = lambda { |link, page| link }
      @scheme_handlers['https']     = @scheme_handlers['http']
      @scheme_handlers['relative']  = @scheme_handlers['http']
      @scheme_handlers['file']      = @scheme_handlers['http']

ここ 1 か所だけなんだがな―。直してオレオレ gem を作ればいけるのか?
とりあえずフォークしてみた。けど、それからどうすりゃいいんだ?

同日追記

とりあえずローカルで直してみた。@scheme_handlers は事実上いらないのでさっぱり消した。生成したばかりの Mechanize オブジェクトはシリアライズできるようになった。しかし一度アクセスするとソケットが開きっぱなしになるらしく、ソケットはシリアライズできないので、やっぱりだめぽ。…いちいちソケットを閉じて破棄するようにするか??

*1:Mechanize は Nokogiri に依存しない旧版 0.8.5 を利用