久々にRailsじゃないCGIプログラムを書くといろいろ勉強になるけど、ひどくハマる。
レンタルサーバーがRails対応じゃないから仕方ないけど。
で、今回のどハマりはマルチパート。
日記みたいなかんじのCGIなんだけど、
画像ファイルをアップロードさせてサーバーのディレクトリに保存、エントリ投稿時にディレクトリのファイルを選択して貼り付ける言う、それほど難しくもないもの。
デザインと分離したいので、rhtmlが使いたかった所だけど、それがサーバーの都合で出来ない。
頻繁に書き換えるわけでもないので、投稿データはYAMLで保存しておき、
テンプレートとしてデザイナーに作ってもらったファイルの一部を書き換えることで、
HTMLファイルを再構築して出力するようにした。
根本的な機能はrbファイルで作成して、入出力をcgiに持たせる方向で行く。
そうすれば、CGIから作らなければならないページは管理用のページだけになる。
管理用ページはCGI::HtmlExtentionを使って、出力する。
で、はまったのは、マルチパートフォームで画像をアップしたとき。
1.マルチパートで送ったときは、同一フォーム上のパラメータは全部StringIOできちゃうこと。
これはすぐわかった。
CGI.multipart?で処理を分岐してパラメータの取得をおこなって終了。
2.なぜかcgi.outのところでエラーが返る。
cgi.rb 'read_multipart' : no content body {EOFError)
ときたもんだ。
マルチパートの処理は正常に終わってるし、サーバーにも意図通りファイルが保存されている。
何だ何だー?
と調べてみると、CGI.newが再度呼ばれているところが原因。
どういうことかというと、
ページ全体の設定だとか、エントリの編集部分だとか、画像の選択フォームだとかの定型的なものはどうしても繰り返し書いてしまいがちなので、ここは一つDRYにするために、出力部分のヘルパを作ってみた。
特に何も考えず、どうせCGI::HtmlExtentionで出力された文字列をあいだにはめるだけだから、とヘルパにはクラスメソッドのみしか定義せず、出力に必要なオブジェクトのみを引数にして、メソッドが呼ばれるたびにCGI.newしていた。
この部分だ。
うへー。と思いつつ、クラスメソッドにするのをやめて、initializeで呼び出し元のCGIインスタンスを引き回すことにする。
CGI::HtmlExtentionがクラスメソッドじゃないのには理由があるんだねえ。
クラスメソッドじゃないものをクラスメソッドの用に使い回すのにインスタンスを作りまくるのはやっぱ問題があるんだねえ....
CGI::HtmlExtentionでどうしてクラスメソッドじゃないのかは調べる気力がないのでここで終了。
教訓
ヘルパ作るなら、CGIインスタンスを使い回せ。
無駄にnewすんな。PR