【Ruby】RubyでCGI

このエントリーをはてなブックマークに追加
928nobodyさん:2005/05/29(日) 23:35:24 ID:???
927は過去になんかあったのか?
いったい何の説明してるんだ?
MySQL じゃなくSQLite の話じゃないし、SQLite スルーの話でもないしな。

cgi.rbが1.6と1.8で挙動が違うなら、cgi.rbの代替が必要になってくるのは当然だし、
どこのレンタルサーバでも動くようにするには、標準ライブラリか、Pure Rubyなライブラリ使うのは当然だしな。
929nobodyさん:2005/05/30(月) 00:10:08 ID:???
おまいらなんのはなしをしているんですか?
930nobodyさん:2005/05/30(月) 00:34:06 ID:???
>>929
スレタイ読め
931nobodyさん:2005/05/30(月) 09:28:29 ID:???
過去の経緯は知らんが。

SQLiteはいいものだが板違い。
db板にスレがあるから行ってこい。
DBI-sqliteについての話だったらム板へ。
932nobodyさん:2005/05/30(月) 20:26:39 ID:???
1.6と1.8で挙動が違う部分って、何?
cgi.params["name"][0]
ってやればどっちでも大丈夫なんでしょ?
933nobodyさん:2005/05/30(月) 20:36:02 ID:???
934932:2005/05/31(火) 22:15:56 ID:???
>>933
ありがd
読んだけどよくわからんかった;
挙動が違うのはcgi["name"]って書いたときの話ですよね。
しかし、「1.6と1.8両方で動くスクリプトが書けない」っていうくだりは本当ですか?
レシピブックにはcgi.params["name"][0]って書けばオッケーって書いてあったんだけど・・・
935nobodyさん:2005/06/02(木) 14:07:03 ID:???
>>934
「1.6と1.8両方で動くスクリプトが書けない」というのは
リンク先にもあるようにCGI#[]を使うときの話。

>cgi.params["name"][0]って書けばオッケー
言い方を変えれば「CGI#paramsを使わなければダメ」。
あと既存のスクリプトがCGI#[]を使ってたりすると、
いちいち修正したりするのも億劫だよね。
そこのところを気に入らない人はいるんじゃないかと。
936nobodyさん:2005/06/03(金) 13:33:14 ID:???
なるほど。
しかしcgi[]の[]ってメソッドなのな。
Rubyは奥が深い・・・

どんなメソッド定義してるのか今度みてみよっと。
937nobodyさん:2005/06/05(日) 11:59:22 ID:???
>>935
いちいち修正して億劫というのが、あちこち修正という意味なら、
1.6の方に CGI#[] を定義すればいいだけじゃねー?
938nobodyさん:2005/06/09(木) 06:33:46 ID:???
RubyCGI.orgの
http://www.rubycgi.org/cgi_explanation/3-5.htm から
一部コメントを付け加えて抜粋。

#書き込みがあったら
if senddata
 begin

#ファイルロック設定
 lockd = fillock.lock(LOCKFILENAME)

  unless lockd
   print <<EOF;
   <html><body>
   他の人が書き込み中です。しばらく待ってからもう一度書いて下さい。
   </body></html>
   EOF
  end #unless end

#ログファイルの書き込み関数を呼び出し
 write_log_file(senddata)

 ensure
#ファイルロック解除
  fillock.unlock(LOCKFILENAME) if lockd
 end #begin end
end

これ、正しくファイルロック出来てるんでしょうか?
このままだとロックの状態に関わらず書き込み関数を呼び出して
ファイルをいじってしまうように思うんですが・・・。
939nobodyさん:2005/06/10(金) 08:02:01 ID:???
FILELOCKで示されるディレクトリを作ってためしてみたら?ちゃんと動くはずだけど。

このプログラムは無理にクラスとかメソッドを定義しててわかりにくいね。

手続き型で書いてもRubyはきれいに書けるんだけどな。
940938:2005/06/10(金) 08:56:02 ID:???
>>939
そっか、自分でディレクトリ作ればいいんですよね。
何でそんな単純なこと思いつかなかったんだか・・・。
ありがとうございます。

で、実際にやってみたところ
やっぱり正しくファイルロックできてないみたいで、
ディレクトリの有無に関わらずガンガン書き込んでます・・・。

unless lockd
 今は書き込めませんメッセージ
else
 write_log_file(senddata)
end

多分こんな風に、書き込み関数をunless elseの中に入れちゃえば
正しく動くんじゃないかと思います。(試してませんが)

クラスや関数を作りまくってるのは
「作り方を学ばせるためにあえて」
ってことだと僕は思っているんですが・・・、
人によっては「これが良い書き方なんだ」って勘違いしちゃいそうですよねえ。
941nobodyさん:2005/06/10(金) 11:42:39 ID:???
>>940
そのコードはダメポ。

せっかく全体をbeginで囲っているんだから、例外的事象(ロック失敗)に対応する
コードはrescueブロックに配置すべき。

そのためには、FileLockDir::lock の中で、ロックに失敗したら例外を投げる
ような仕様にするのがいいと思う。

FileLockDir自体、initialize(ファイル名) にして、lock/unlock に引数が
いらないようにしないと、わざわざインスタンスを生成する意味がないし。
942940:2005/06/10(金) 12:14:40 ID:???
>>941
アドバイスありがとうございます。

>コードだめぽ
これは
「お前の書いたコードじゃ正しく動かねーわ」って意味ですか?

それとも
「そもそもサイトのサンプルコードからしてゴチャゴチャしてるから
 そっから考え直して、まとめた方がいんじゃね」
って意味でしょうか?
943941:2005/06/10(金) 12:29:50 ID:???
>>942
すまん、サンプル自体がまずいと言いたかっただけだよん。
944942:2005/06/10(金) 12:38:31 ID:???
>>943
確かにサンプルコードを基本にして手を加えていくと、
どうもきれいにまとまってくれません・・・。
構造から考え直してみます。
945nobodyさん:2005/06/10(金) 22:30:12 ID:???
しかし、ネットで拾えるまとまったRuby&CGIの入門用資料ってこのサンプルくらいしかないよなー。

漏れもそのページから入ったクチなんだけど、最初はクラスとかメソッドとかわからんからとりあえず部品を全部ばらしてみたもんだ。

表面上のRubyらしさをムリヤリ加味するとこんなコードになるという生きた見本。いろんな意味で価値あるサンプル。

漏れはこのサンプルに感謝しているよ。
946nobodyさん:2005/06/11(土) 16:43:30 ID:???
CGI抜きにして「Ruby入門サイト」を探しても、かなり少ないしね。
しかも大体古くて、今はもう更新されて無いようなところばかり。
さすがにこの現状は切なすぎる・・・。
誰か新しく入門サイト作ってくれないかな。
(・・・と、他人に期待するばかり)
947nobodyさん:2005/06/11(土) 19:24:16 ID:???
>>945
ムリヤリとかいろいろな意味でとか、変な皮肉はヤメレ
948nobodyさん:2005/06/11(土) 23:19:24 ID:???
>>946
本スレで出てた気がするが、
Rubyの入門としてはこれを押す。

tp://www1.tf.chiba-u.jp/~shin/tutorial/

これ自体は CGI スクリプトみたいだが。
949nobodyさん:2005/06/11(土) 23:55:00 ID:???
>>946
入門サイトって似たり寄ったりな内容じゃない?
定番があれば十分で、数が多くても意味がないと思うけどなあ。
950nobodyさん:2005/06/12(日) 16:27:33 ID:???
>>949
日本語のRubyの入門サイトの中で定番といえるほど有名なものってある?
951nobodyさん:2005/06/12(日) 17:16:57 ID:???
>>949
サイトが増えると、サンプルが増える。
あと、ユーザーのレベル・好みでサイトを選べる。
(プログラム初心者ってわけでなければ
 『一時間で覚えるRuby』でもいいわけで)

俺が思い付くのはこれくらいかなー。
もちろん「質より量だ!」なんて言うつもりはないけど
数は多いに越したことないと思うよ。
952nobodyさん:2005/06/12(日) 19:35:57 ID:???
953nobodyさん:2005/06/12(日) 21:58:26 ID:???
>>952
分類されていないから、
どれが入門用ドキュメントで、
どれが特定の話題に特化したドキュメントなのか
分かりにくい。

個人的には下のが良さげ

http://ruby.mirror.easynet.be/ja/uguide/uguide00.html
http://ns.wisdom.co.jp/~ono/programming/ruby/intro/intro_01.htm
http://homepage1.nifty.com/~tetsu/ruby/intro/
http://www1.tf.chiba-u.jp/~shin/tutorial/

http://linux-life.net/program/ruby/
http://www.namaraii.com/rubytips/
954nobodyさん:2005/06/17(金) 01:12:56 ID:???
メールフォームを作りたいんですが、いい資料ありますか?
955nobodyさん:2005/06/17(金) 18:36:09 ID:???
つ rfc2822
956nobodyさん:2005/06/17(金) 20:08:02 ID:???
>>955
そういうことではなかろう。
957nobodyさん:2005/06/19(日) 13:13:02 ID:Le0SqOYO
WEBrick でCGI (servlet?) を書こうと思ってるんですけど、
どうもCGIの処理が完了してから纏めて全部出力しているようです。
これって少しずつ逐次出力することはできないでしょうか?
帯域を制御してストリーミングがしたいのですが。
958nobodyさん:2005/06/20(月) 02:28:39 ID:???
まさかTCPのバッファリングを制御したいとか、そういう話しじゃないよね?
959nobodyさん:2005/06/20(月) 14:53:07 ID:???
そこまで低レベルなレイヤーでないと制御できないことなのですか?
帯域制限はCGI 側で行うので、httpdは即座にデータを送出してくれれば
それで十分なのですが。

それと、出力全体がバッファされると言うことは、送るデータのサイズと
同じだけメモリを消費するわけですよね。
これでは実質数十MBくらいが限度です。
どうにかならないものでしょうか。
960nobodyさん:2005/06/20(月) 15:01:12 ID:???
WEBrick は素人なんだけど、 res.body に IO のサブクラスを指定すると、
IO から少しずつ body を返すようになる気がする。
webrick/httpresponse.rb の WEBrick::HTTPResponse の
send_body とか send_body_io とか見てみると良いかも。
961nobodyさん:2005/06/21(火) 10:04:08 ID:???
IOからサブクラスでreadとcloseを再定義することで解決できました。
どうもありがとうございました。

ちなみに最初は単に IO.pipe の入力側を渡してでマルチスレッドに
するつもりだったのですが、先に入力待ちするとデッドロックします。

pi, po = IO.pipe
t = Thread.start {
 print while (Thread.stop or pi.gets)
}
po.puts "first"
t.wakeup # OK
t.wakeup # dead lock
po.puts "second"

これはこういうものなのでしょうか?
IO.popen('-', 'r') も動かないし、windows版の制限なのかな。
WindowsXP SP2, Ruby 1.8.2 (ActiveScriptRuby 1.8.2.0)
962nobodyさん:2005/06/21(火) 10:57:54 ID:???
上のコード、IRB上なら止まるんですが、直接実行だと動きますね。
これでどちらもデッドロックするようです。

t.wakeup # OK
sleep 1
t.wakeup # dead lock
963nobodyさん:2005/07/03(日) 10:37:19 ID:???
ロリポップがサーバーのバージョンアップ及びモジュール追加ってやつで、
ruby (1.8.2)に対応したみたいで・・いいことなのですが、
なぜかそれ以降動かなくなったCGIが出ました;

ローカルでのテスト環境は 1.8.1 で、それで動いているのですが動きません。
一番上のパスが違うのかなと思ったら、他のRubyで作ったものは動いていました。

何らかの実行時のエラーで落ちてるのかと思い、全体を
begin
# 全体の処理
rescue Exception
File.open("erorrlog/#{Time.new.to_i.to_s}.err", 'w'){|f| f << "#{$!}(#{$!.class})\n#{$@}"}
end

ってな感じでログを残そうとしても、ログが残りませんでした;;
かなりお手上げです。詳しい方、教えていただけたら幸いです。
964nobodyさん:2005/07/03(日) 14:32:34 ID:???
>>963
ログは見れないの? rescue できないとすると文法エラーかな?
965963:2005/07/04(月) 01:28:46 ID:???
うーん、なんかヒアドキュメントで文法エラーが出てるような・・
ローカルでも 1.8.2 で試したけど動きましたが・・OSによって違うのかな・;
966nobodyさん:2005/07/04(月) 09:14:56 ID:???
>>965
ロリポップにログくれって言えないの?
少なくとも同じバージョンなら違うマシンでも文法は同じはずなので
同じバージョンでテストしてますよというのを伝えた上で、ロリポップにその辺聞いて見れ。
967963:2005/07/04(月) 23:58:18 ID:???
あ、やっぱヒアドキュメントじゃないっぽい;
#!/usr/local/bin/ruby -Ks -Ilib
↑の1行目のオプション -Ilib がまずいっぽい・・ような・?
やはりこれもローカル(windows)では動いてます;

ちなみにロリポップにはまだ聞いてません。すまん。
968nobodyさん:2005/07/05(火) 00:39:22 ID:???
>967
思い切って別PCにLinux入れてみるとか、あるいはcoLinux入れてみるとかして
UN*Xな環境作って試してみるのはどうか。
969nobodyさん:2005/07/05(火) 12:56:07 ID:???
>>967
-Ilib じゃなくてフルパスで指定してみたら?
970nobodyさん:2005/07/05(火) 22:29:14 ID:???
CGIを別名にリネームして、元のCGIファイル名で次のようなのを作る。
#!/bin/sh
exec リネーム後のCGI > ログ.txt 2>&1

CGI実行後に ログ.txt を見る。
971963:2005/07/06(水) 00:09:55 ID:???
-Ilib のオプションを使わずにしたら、いままで動かなかったものがすべて動きました。
>>970 さんのものも試してみましたが、500エラーというのが出て、ログは残りませんでした。

どうして、-Ilib が使えないのかはわからないままです;
972nobodyさん:2005/07/06(水) 14:05:13 ID:???
lib ディレクトリに 1.8.2 で動かない古いライブラリが入っていたと想像。
973nobodyさん:2005/07/18(月) 02:45:10 ID:???
マルチパートなフォームのデータを送信した場合、スクリプト内の
CGI.new
のところで
in `read_multipart': no content body (EOFError)
というエラーが出ますが、これは何ですか。
環境は WindowsXP + Apache + Ruby 1.8.2 です。
974973:2005/07/18(月) 17:27:49 ID:???
【つづき】

原因究明のために cgi.rb の 976 行目付近

status = stdinput.read(boundary_size)
if nil == status
raise EOFError, "no content body"
elsif boundary + EOL != status
raise EOFError, "bad content body"
end

での、status 変数について調べました。
if 文で評価される前の status は String で、

"malformed header from script. Bad header=-----------------------------7: index.cgi"

という値でした。
しかし,条件文にさしかかったところで status 変数の中身が nil になってしまうようです。
print 文で status 変数の中身を表示させてみましたが、一回目の print 文で上記の文が出るものの、二回目以降は何も表示されませんでした。
どなたか原因と解決策をご存知の方、ご教授ください。
975nobodyさん:2005/07/18(月) 18:01:01 ID:???
最小再現コードがあれば誰か調べるんじゃない
976973:2005/07/18(月) 18:19:41 ID:???
>>975
最小再現になるようにコードを追っかけていたところ、
エラーの発生箇所が思っていたのと違う箇所だということがわかりました。
エラーが発生したときのエラー表示のために
CGI クラスを使っていたのですが、
もう一度 CGI.new したときに、上記のエラーが発生していました。
因みに、このとき最初に rescue していたエラーは

cannot convert StringIO into String

で、まったく別物でした…

出直してきます…
977nobodyさん
質問させていただきます。

open-uriによってカウンターがついているウェブページの中に、カウンターを更新させないページがあることに気づきました。

どなたか理由と、どうすれば反応するようになるか教えていただけますでしょうか?

よろしくお願い致します。