青山です。

On Tue, 5 Oct 1999 11:47:17 +0900,
Koichi Shigematsu <shige / ecc.denso.co.jp> wrote:

> さて、cgi.outでヘッダーを書かせると、Content-Lengthがセットされてしまい、
> その後、print文でたらたらと書かせると途中でとぎれた感じで表示されます。
> 
> そこで、この"Content-length"を出力させないようにしたいのですが、
> よくわかりません。 過去ログも当たったのですが見つかりませんでした。

どうしても出力させたくない場合は cgi.out を使用せず自前でヘッダを出力
する事になると思いますが、おすすめはしません。

Content-Length を渡さないという事は、クライアント側ではホストから切断
されるまで受け取り続けるしかなく、効率が悪い上に、きちんとすべてのデー
タを受け取れたかどうかの確認の手段もなくなります。

HTTP 1.1 では chunk という塊で送るというようになっていくようですし、サー
バー、クライアント、途中経路等、すべての為にも、ばらばらに送る事はせず、
まとめて、Content-Length を付加する事をおすすめします。

require 'cgi'

cgi = CGI.new("html4")

cgi.out() do
  cgi.html( "PRETTY"=>($DEBUG ? "  " : false) ) do
    cgi.head() do
      cgi.title{ "title" }
    end +
    cgi.body() do
      cgi.form( "post", "hogehoge" ) do
        "string"
      end
    end
  end
end

まだ参照できるコードも少ないので悩まれたのかもしれませんが、処理が短い
場合は、こんな感じで form 等もまとめて書くと見やすいです。String を渡
すようになっていれば、外部に処理を置いて、cgi.body(){ foo } のように
引き渡しても良いでしょう。(foo は String を返すとして)

また、String であれば良いという事は、
cgi.body{ '<FORM METHOD="post" ACTION="hogehoge"></FORM>' }
のような感じでも書けます。

しかし、自前でエレメントを入れてしまうと、cgi.html が付加する DOCTYPE
宣言にそったエレメント以外を入れてしまう可能性や、タイプミスが発見でき
ない等の不便さもあるので、メソッドを利用される事をおすすめします。

メソッドを利用した場合は、DOCTYPE に対応しないメソッド名はエラーになり
ますし、タイプミスも当然エラーになりますから、早めに問題を発見できます。

属性の指定については、先の例のように form(METHOD, ACTION) というような
利便性の為に拡張された形式をもつものもありますが、その場合でも、
"ATTRIBUTE"=>"bar" という形式が常に共通して利用できます。

cgi.form( "METHOD"=>"post", "ACTION"=>"hogehoge" ) do
  "string"
end

cgi.a("url"){"string"} 等も、cgi.a("HREF"=>"url"){"string"} という感じ
ですね。一々書き方を調べる手間が不要になりますし、他の人が見ても HTML
の記述を覚えていれば読めるので、このような書き方で統一してしまうのも良
いでしょう。


-- 
青山 和光 Wakou Aoyama <wakou / fsinet.or.jp>