Ruby で CGI > 出力方法 > 問題
アクセスする毎にテキストで表示される数字が一つづつ増えて行く CGI を作成してください。 html である必要はありません。いろいろ工夫してみてください。
♪
f = File.open("count.txt","r") n = f.read(23) f.close
,"r"
は動作を指定するオプション(r,rb,w,wb,a などがある)で、文章読み出し,"r"
の場合に限り省略可能ですf.read(23)
でファイルから中身を、23バイト(=英文23文字)を上限として、読み出します。23以外の整数でも同様。(23)を省略すると、ファイルサイズの大きなファイルでも、全部一気に読み出します。f.read
を避け、f.gets
で1行づつ取り出して処理します。while
を使うと、連続して取り出すことができます。下記は、f.read
と同じ内容です。
n = "" while line = f.gets do n += line end
f.close
でファイルの取り扱いを完了します。これをつけないと、ファイルに取っ手がついたままになり、ファイルを読み込み終わる前に、他の動作を並行してやってしまうかもしれませんf = File.open("count.txt","w") f.print n f.close
2
は数字扱いですが、"で囲った "2"
は文字列として扱われます。1 + 2
は3
になりますが、"1" + "2"
は"12"
になります。1 + "2"
については、足し算が定義されていないので、例外(=エラー)が発生します。n
を整数とするとき、n.to_s
は文字列になります。s
を文字列とするとき、s.to_i
は整数になります。"3".to_i
は整数の3
、"あ".to_i
は整数の0
になります。数字以外の文字をムリ繰り整数化すると、みんな0になります。echo 0 > count.txt chmod 706 count.txtと、入力してください。
♪
おそらく、最もシンプルな答えは、数字だけ表示させることにして、
#!/usr/local/bin/ruby file = "count.txt" f = File.open(file,"r") n = f.read f.close n = n.to_i + 1 f = File.open(file,"w") f.print n f.close print <<EOS Content-Disposition: filename="access_count.txt" Content-type: text/plain EOS print n
数字だけでは物足りないという場合、文章をつけることもできます。
#!/usr/local/bin/ruby -Ks file = "count.txt" f = File.open(file,"r") n = f.read f.close n = n.to_i + 1 f = File.open(file,"w") f.print n f.close print <<EOS Content-Disposition: filename="you_are_happy_#{ n }th_visitor.txt" Content-type: text/plain あなたは#{ n }人目の訪問者です! EOS
最初に数字のファイルが無くても、begin 〜 rescue 〜 end の構文で、例外(=エラー)の発生による中断を回避することができます。 ⇒ begin
#!/usr/local/bin/ruby -Ks file = "count.txt" begin f = File.open(file,"r") n = f.read f.close rescue n = 0 end n = n.to_i + 1 f = File.open(file,"w") f.print n f.close print <<EOS Content-Disposition: filename="you_are_happy_#{ n }th_visitor.txt" Content-type: text/plain あなたは#{ n }人目の訪問者です! EOS
参考:ファイルの読み書きの記述をかなり省略して縮めることができます。
#!/usr/local/bin/ruby -Ks file = "count.txt" n = open(file){|f| f.read } rescue 0 Process.waitall if RUBY_VERSION.to_f >= 1.7 n = n.to_i + 1 open(file,"w"){|f| f.print n } rescue 1 print <<EOS Content-Disposition: filename="you_are_happy_#{ n }th_visitor.txt" Content-type: text/plain あなたは#{ n }人目の訪問者です! EOS
open(file){|f| f.read }
⇒ open
File.
を省略できます,"r"
に限り省略できますopen(file)
自体を、後続のブロック{ }
の中に{|f| }
のfとして送ることができます{ }
の中で、最後に評価された値が外に出力されるので、f.read
をブロックの最後に置きますrescue
を後置きで使うこともできます。
ファイルの読み込みに失敗して例外(=エラー)が発生した場合、代わりに rescue に続く部分の値を出力します。 ⇒ rescueProcess.waitall
は、並行して行われる諸々の作業(子process)が全部完了するのを待ちます。複雑な処理系で威力を発揮。ここではただの「おまじない」で、無くても正しく動作します。⇒ Process.waitallProcess.waitall
が使えるのは、ruby のバーションが 1.7 以降です。古い ruby では使えません。RUBY_VERSION
は ruby のバージョンを表します。.to_f
をつけることで浮動小数点数となります。"1.6.8".to_f
は、浮動小数点数の1.6
になるようです。open(file,"w")
⇒ 開くのがファイルだとわかりきっているので、File.
を省略できます以上です。