くまりゅう日記

もっと過去の日記
[.NET | BeOS | Blender | COLLADA | fossil | mono | monotone | NPR | OpenGL | PeerCastStation | Riko | Ruby | Silverlight | TRPG | XNA | ゲーム | ゲーム作り | ]

2010-08-05

_ 日記

寝過ぎると帰ってきて寝て起きて飯食って出掛けるだけになっちゃうな。気をつけよう。

るびま用にRubyゲーム会議の紹介を書かないといけないんだけどなかなか。 あー、いまさらだがRubyゲーム会議にマスコットキャラがあれば良かったなー。

_ [Ruby] appengine-jruby

某イベントのページ作るのにまたGoogleAppEngineを使うのでappengine-jrubyを使ってたんですよ。

前回はRack素+なんかテンプレートエンジン*1+素でDatastore使うなどかなり力技で組んでたんだけど、今回はもうすこしおとなしく、sinatra+erb+datamapperで。

DataMapperとかよくわからんけどなんか動いた。何が起きてるのかあまりにもよくわからないんだがこれでいいんだろうか。不思議である。

しかし動いたと思ったらやっぱり動いてなくてsqlite3にバイナリの0をつっこもうとしたらNULL文字扱いされるのかそこで値が終わってしまった。dm-appengineならBlobって型指定ができるんだけどdm-sqliteにはないわ。本番ではsqliteいらないのでin_memoryてのを指定して回避できた。

SinatraはRack::Testでテストできるよって書いてあるんだけど、Rack::Testが無いんですよ。さんざん探したらrack-testを別途入れないといけないことにしばらくして気付いた。別途入れるならそう書いてよ…。

Rack::Testでクッキーを食わせたことをテストしようとしたけど全然わからなかったので諦めた。

というかテストは普通のRubyで動かしてるんだけど、これappengine-jrubyのローカル開発環境でも動かせるんだよなきっと?やりかたわからないのでこれも諦めたが。

そんなこんなで画像のアップローダが出来てテストは手元でちゃんとうごいたので設置。普通に動いてるなーと思ってたんだけど500エラーで上がんねーとの報告が。

でも俺の画像は上がるなーと思ったら、でかいファイルが上がらない模様。いろいろ試したら64k以上のファイルが上がらない。

エラー場所はJRuby版Rackの中?StringIOをTempfileにキャストできねーよ!ってさ。知らんがな。

appengine-rackではTempfileをStringIOに置き換えてるようだ。これはAppEngineでTempfile作れないからだね。わかる。

JRuby版Rackでは入力が一定サイズ(既定で64k)を越えたらTempfileを使うようにしてる。これもわかる。

Tempfileを作るところはJavaのRubyTempfileクラスにRubyのTempfileクラスを渡してRubyオブジェクト作ってねーってやって、戻り値をRubyTempfile型の変数につっこんでる。appengine-jrubyだとRubyのTempfileはStringIOのサブクラスになっちゃうのでこのキャストはできなくて例外。

場所は分かったんだけど原因と解決法はどうすりゃいいんだ。appengine-jrubyのバグかと思ったけど特に報告も出てないようだし俺の使い方なり環境がおかしいというのも排除できないな。

どうしようか悩んだけど、夜だったのでとりあえず動かして寝たい。Tempfile作ってるorg.jruby.rack.RackRewindableInputにDefaultThresholdというstaticフィールドがあってこれがTempfileを作るかどうかの判定に使われてる。閾値以下のサイズはメモリに保持するようになってるんでStringIOと同じ意味だし、閾値をめっちゃ上げて対処したい。

JRubyはいまいちよくわからなかったが、適当に書いたら動いた。

##highlight ruby
if defined?(JRuby) then
  import org.jruby.rack.RackRewindableInput
  RackRewindableInput.default_threshold = 1024*1024*1024
end

これをconfig.ruの頭の方に書いといた。 1GBもいらないんだが適当に。いやでかすぎてまずいかも。まあ動いてるからいいか。

*1  radiantとかなんとか

_ [Ruby] GLSLパーサ作り

ソース整理してちょっとすっきりした。

pragmaディレクティブをすっかり忘れてたのも追加した。

includeディレクティブは拡張で追加されるのは分かったんだけど、拡張は別ファイルをrequireするとパースできるようにしたいと思って考えてみた。

まあもちろんできなくはないが、何も考えずに作るとルールは後から上書きするしかない。上書きはたぶんできたはず。

たとえば

##highlight ruby
#in tokenparser.rb
rule :directives do
  any(
    :define_directive,
    :if_directive,
    :line_directive,
    (中略)
    :unknown_directive)
end

こんなルールがあったとしよう。:directivesはいずれかのディレクティブにマッチするルールということを定義してるんだけど。

こいつに#includeディレクティブを追加したい。

##highlight ruby
#in include_directive.rb
rule :directives do
  any(
    :include_directive, #追加したぞ!
    :define_directive,
    :if_directive,
    :line_directive,
    (中略)
    :unknown_directive)
end

追加するだけなのに全部コピペ上書きかー。

仮にここに新しく#nantokaディレクティブが追加されたときはどう対処すればいいんだろうか。nantoka_direcitive.rbは#includeについては記述するべきじゃないだろうけど、上書きだから入れないと#includeのパースルールが消えちゃうね…。

というわけで単に上書きするのは無理か。

##highlight ruby
#in tokenparser.rb
Directives = [
  :define_directive,
  :if_directive,
  :line_directive,
  (中略)
  :unknown_directive,
]
rule :directives do
  any(*Directives)
end

こんな感じにしておけばDirectives定数にルール名を追加するだけで増やせるんだけどね。でもこれを拡張できそうなところ全部に仕込んでいくのは大変かも。あとこのままだと展開のタイミングがはやすぎる。

無駄に悩んでるよりも手動かしちゃった方が早いかもねー。


ページのトップへ | トップ «前の日記(2010-07-30) 最新 次の日記(2010-08-09)» | 編集 | kumaryu.net by kumaryu