Ruby初心者スレッドPart8
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2006/09/28(木) 15:28:59関連スレやURLは2以降。Ruby on Railsの質問はWebProg板のRailsスレで。
■質問する人へ
質問する前に次の3つをすること。ここで回答を待つよりそのほうが早い。
・ぐぐる
・マニュアルで探す http://www.ruby-lang.org/ja/man/
・FAQを読む http://ruby-lang.org/ja/man/?cmd=view;name=Ruby+FAQ
質問には以下を書くこと。へたくそな質問は再提出を要求される。
・詳しい内容(「動きません」「うまくできません」では回答しようがない)
・エラーメッセージ(なるべくそのままで)
・実行環境(OS名、Rubyのバージョン(ruby -v でわかる))
・最終的にやりたいこと(もっとよい方法がある場合が多いので)
回答してくれた人には「ありがとう」のひとことをいってあげて。
■回答する人へ
相手は初心者、根気よく育てるつもりで。質問がへたくそなのも大目にみてあげる。
それができないならこないこと(だって初心者スレだもん)。
・既出な質問やFAQは「XXXを読め」でいいので、叩かない&怖がらせない。
・わけわかな質問にもエスパー発揮で。できれば質問の仕方を教えるぐらいで。
・自信がない回答ならその旨表明すること。誤った回答は初心者じゃ見抜けない。
宗教的な話題は禁止します。
0446デフォルトの名無しさん
2006/11/01(水) 14:08:22というのを文字列sが10MB分くらいになるまで繰り返すんですが
前もってバッファを確保しておいて高速化してくれるものはないですか?
StringBuffer/Builderみたいなの。
0447デフォルトの名無しさん
2006/11/01(水) 14:32:560448デフォルトの名無しさん
2006/11/01(水) 14:47:16バッファを用意しておくよりは遅いかもしれないけど、計算量的には同等のO(N)になるし、10MBもあるなら文字列の連結を繰り返すO(N**2)よりは断然早くなることは期待できる。
まあバッファを用意できる方法がもしあればそれに越したことはないんだろうけど、もしないなら配列にpushしてjoinも捨てたもんじゃないと思われ。
0449デフォルトの名無しさん
2006/11/01(水) 17:07:47# 文字列に直接連結
s = ""
t = Time.now
for i in 1..10000
s += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
end
f = File.open("test1.txt", "w")
f.write s
f.close
p Time.now - t
# 配列格納後に連結
s = ""
t = Time.now
a = []
for i in 1..10000
a << "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
end
s = a.join
f = File.open("test2.txt", "w")
f.write s
f.close
p Time.now - t
結果
10.281
0.032
サイズは 1MBに満たないけど、けっこう差が出るな。ruby 1.8.5 (2006-08-25) [i386-mswin32] Athlon64 2800+
0450デフォルトの名無しさん
2006/11/01(水) 18:52:340451デフォルトの名無しさん
2006/11/01(水) 19:52:49やってみた。こっちも速かったのでデータ量を100倍(およそ100MB程度)にしてみた
ただし、ファイルの書き込みはなし(100MBだと本来の速度が分かりにくくなるため)
結果は、ほぼ join と同じだけど、統計的にはわずかに配列のほうが速いかな?
微妙すぎるので、CPUの違いで結果が変わるかも知れませんね
1.219 (配列 join)
1.234 (文字列<<連結)
それにしても、+=演算子があんなに遅いのはなんででしょ?
単純計算で300倍くらい違ってるんだけど、どこでそんなに時間食ってるのやら…
# 配列格納後に連結
s = ""
t = Time.now
a = []
for i in 1..1000000
a << "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
end
s = a.join
p Time.now - t
#文字列に<<演算子で連結
s = ""
t = Time.now
for i in 1..1000000
s << "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
end
p Time.now - t
0452デフォルトの名無しさん
2006/11/01(水) 20:09:53はRubyのパーサが中で
s = s + "hogehoge"
と置換していて、Stringのインスタンスを毎回生成するので遅い。
Javaで
s+"hogehoge"+"hugahuga"
としたときに内部で(俺の記憶では)
new StringBuffer(new StringBuffer(s).append("hogehoge")).append("hugahuga")
となっていたのと似ている。
まあ何カ所か短い文字列を結合するだけでは違いは出ないと思うが。
あと、実用できないけど、この場合
x = "aaa...."
for i ...
a << x
のほうが早いのではないかと。
0453デフォルトの名無しさん
2006/11/01(水) 20:14:40実験ありがとう。配列join早いなあ。
ところで、試してないけど、この例みたいに回す回数が決まってるなら、
a = Array.new(1000000)
for i in 1..1000000
a[i] = "aaa...
end
の方が早かったりしないかな?
0454デフォルトの名無しさん
2006/11/01(水) 20:17:36GC。a+=b ってのは a = a + b の略だから、これをする毎に前の a がごみに
なる。a << b は a を延長して追加するからごみが出ない。Rubyは単純な
mark&sweepだからごみが増えればGCの処理時間も比例して増える。
参照カウントベースのGCを持つPythonで試してみ、a+=bでもめっちゃ速いから。
ごみになった瞬間に回収されるから、mark&sweepの負荷がない。
0455デフォルトの名無しさん
2006/11/01(水) 21:55:07+=の場合は、
a
aa
aaa
aaaa
aaaaa
っていう風に、内部でコピーしなければならない文字列の長さがどんどん長くなっていくから、N回のループで(N*N/2)回(三角形の面積)かかる。
追加していくタイプは、一回一回の操作にかかる時間はどんなにaaaa・・・の長さが長くなっても、一定時間で追加できるから速い。
もちろんGCのほうにも同じだけの負荷は回っていると思うけど。
0456デフォルトの名無しさん
2006/11/01(水) 22:31:21ピンと来ないし面倒だなあ
0457デフォルトの名無しさん
2006/11/01(水) 22:38:26素直にStringBuilder的な物をサポートすべきだな。
といってもされないだろうからRuby.NETに期待だ。
0458デフォルトの名無しさん
2006/11/01(水) 22:48:210459デフォルトの名無しさん
2006/11/01(水) 23:05:43RUBY_PLATFORM 以外に何かありますか?
0460442
2006/11/01(水) 23:59:08次のようにしてtestlogがほぼ期待通りに生成されることを確認しました。
require 'pty'
require 'expect'
class ScriptTest
def start
PTY.spawn('script testlog') do |r_f, w_f, pid|
p [:pid, pid]
w_f.sync = true
$expect_verbose = false
timeout = 3
w_f.puts 'echo "hoge"'
STDOUT.flush
r_f.expect('$ ', timeout) do
w_f.puts 'exit'
end
r_f.read
end
end
end
a = ScriptTest.new
a.start
STDOUT.flushは気休めだと思うけど、なんとなくつけてみました。
0461デフォルトの名無しさん
2006/11/02(木) 00:04:45アホやなぁ。
RubyはJavaと違ってStringがmutableなんだよ。
だからRubyのStringはStringBufferなんだよ。
+=のとき最適化されないのはおかしいとか言ったら張ったおすよ。
Javaではそもそも+=すら出来ないでしょ。
0462デフォルトの名無しさん
2006/11/02(木) 00:07:39>参照カウントベースのGCを持つPythonで試してみ、a+=bでもめっちゃ速いから。
遅かったよ。GCがどうとかは的外れだな。
0463デフォルトの名無しさん
2006/11/02(木) 00:40:340464デフォルトの名無しさん
2006/11/02(木) 00:50:49GC.disableしてからループ回してみたらどうだろう。
俺はGCがネックでもネックでなくても構わんのでやらんけどw
0465デフォルトの名無しさん
2006/11/02(木) 01:06:37そうか?俺のとこではかなり違うけど。
#### python 0.01秒 ####
import time
t1 = time.time()
s = ""
for i in xrange(50000):
s += "a"
t2 = time.time()
print t2 - t1
#### ruby 17.346秒 #####
t1 = Time.now
s = ""
50000.times do
s += "a"
end
t2 = Time.now
p t2 - t1
0466デフォルトの名無しさん
2006/11/02(木) 01:33:08なんでPythonとこんなに違うのか知らんけど、GCのせいならゴミの数が同じ
下のコードで早くなるのはおかしくね?
t1 = Time.now
100.times do
s = ""
500.times do
s += "a"
end
end
t2 = Time.now
p t2 - t1
0467デフォルトの名無しさん
2006/11/02(木) 02:48:29アホやなぁ。RubyのStringでどうやってバッファを確保しろっちゅんじゃ。
0468デフォルトの名無しさん
2006/11/02(木) 03:03:26マジバカなのか?
0469デフォルトの名無しさん
2006/11/02(木) 03:22:57ディレクトリに戻ってしまうのですが、そうならないようにする方法はありますか?
0470デフォルトの名無しさん
2006/11/02(木) 03:30:040471デフォルトの名無しさん
2006/11/02(木) 03:30:12>>448
参考までに、Perlなら配列のサイズを広げるオーバーヘッドで、pushしてjoinより単純に連結する方が速くなるそうだ。IBMの記事より
>>452
Javaの部分が間違ってる
s+"hogehoge"+"hugahuga"
はコンパイルすると文字列定数はくっついて
new StringBuffer().append(s).append("hogehogehugahuga").toString()
もし"hogehoge"が変数tでも
new StringBuffer().append(s).append(t).append("hugahuga").toString()
で生成するStringBufferは1つ
>>461
>RubyのStringはStringBufferなんだよ
少し違う。たしかに可変長だがStringBufferはバッファが不足したら一気に元の2倍(自信なし)の容量を確保する。newのコストを減らすために。
>Javaではそもそも+=すら出来ないでしょ
できます。コンパイルされてStringBufferの式になおされる。
そして話が噛み合っていない人たちがいるようだが、エスパー的に解釈して
457は、JavaのStringBuilderのように、あらかじめバッファを確保しておく機能が必要だと言っている。コードで示せば
new StringBuilder(131072);
461は、JavaのStringは一度生成したらreallocできない、可変長という意味でStrinBufferと同じだと言っている。
0472デフォルトの名無しさん
2006/11/02(木) 08:52:31GC はメモリを自前で管理する手間が少なくなるが
逆にそれを管理するのは面倒なものだよ
0473デフォルトの名無しさん
2006/11/02(木) 09:00:450474デフォルトの名無しさん
2006/11/02(木) 09:21:15エスパーにもう一つ質問したいんだが、RubyのStringで<<が何らかの形で最適化だか高速化だかがなされるのは、どういう仕組み?
文字列本体の内部表現として、「連続するメモリ領域(Cでいう配列)」を採用しているならば、連結する度に毎回malloc/reallocの類をするのは避けられないのでは?
・Rubyのpushが速いのは、線形リストの連結一回一回は一瞬でできるため。
・StringBuffer等バッファを使うと速いのは、一回一回の連結時にはすでに存在するメモリ領域に入れればいいだけであるため。
・Ruby等の+=然り、Perlのpush然り(?)、が遅いのは、連続するメモリ領域の形になっていて(つまり線形リストの類ではない)、おおよそ連結するたびに、�@全体をメモリ確保する処理と、�A元のデータをコピーする処理が発生するため。
っていう感じの認識なんだが、そうするとRubyの<<が速い理由がよくわからん。
>>452の言うとおり、RubyのStringはStringBuffer的な機能を果たすのか?
ソース嫁ばわかることかもしれんが、ちょっとした気の迷いで他力本願でいってみる。
気付いたら長文になってた。ゴメソ
0475デフォルトの名無しさん
2006/11/02(木) 09:42:120476デフォルトの名無しさん
2006/11/02(木) 09:49:140477デフォルトの名無しさん
2006/11/02(木) 10:11:57Shell.cd(dir)とやると
shell: current dir: なんとか
と表示されるのですが、直後にp Dir.pwdとすると、カレントディレクトリは
変わっていませんでした。
スクリプトを起動した元のシェルに移動先ディレクトリのパスを渡す・・・というのはどうやる
のでしょうか。
0478デフォルトの名無しさん
2006/11/02(木) 10:21:23少なくとも、標準添付されなくてはいけないほどの需要は無いんじゃないかな。
どうしても必要なら自分で拡張ライブラリで実装すれば良いんじゃね?
0479デフォルトの名無しさん
2006/11/02(木) 10:49:16Rubyスクリプトのhoge.rbに
END {
puts '/home/user/path/to/move'
}
とかputsで移動先パスを出力させておいて
DIRNAME=`./hoge.rb`
cd $DIRNAME
というシェルスクリプトでRubyスクリプトを起動する、ってことなんじゃねえの
死ぬほど格好悪く泥臭いがほぼ確実に動作するな
0480デフォルトの名無しさん
2006/11/02(木) 11:02:15raiseでエラーメッセージとして標準エラー出力にパスを出したほうがよくね
0481デフォルトの名無しさん
2006/11/02(木) 16:15:01<< はメソッド呼び出しだが、+= は代入式に展開される。
そうすると、全然 Ruby 側の手順は変わってくるぞ。
s += 'hoge' の場合
・まず s = s + 'hoge' に展開される
・s のメソッド String#+ が呼び出される
・String#+ は s と 'hoge' した新たな String オブジェクトを作って返す
・新たな文字列が s に代入される
・古い s の処理(RubyのGCって何使ってたか忘れたが、マークを外す処理か、実装によっちゃ即廃棄処理だな)
s << 'hoge' の場合
・s のメソッド String#<< が呼び出される
・String#<< は内部領域を拡張してそこに連結する(C言語のrealloc()なのかな?)
差は歴然だろう。
確かに両方とも新たな領域の確保と古い領域の破棄はするんだが
それをRubyのGC管理下でやるのとC言語のメモリ確保でやるのとじゃ全然違う筈。
0482デフォルトの名無しさん
2006/11/02(木) 16:46:06p "a'b".gsub(/'/,"\\\'")
abb
こうなってほしいのですけど。。
a\'b
0483デフォルトの名無しさん
2006/11/02(木) 17:36:32エスケープ文字を3つから4つに増やしてごらん (5つでもいいけど)。
理由はRubyリファレンスマニュアルのString#gsub項を見ることだな。
0484デフォルトの名無しさん
2006/11/02(木) 17:39:480485デフォルトの名無しさん
2006/11/02(木) 18:16:15struct RString {
  struct RBasic basic;
  long len;
  char *ptr;
  union {
    long capa; /* たぶんcapacityのこと */
    VALUE shared;
  } aux;
};
使用しているバイト長とは別に、再確保せずに扱える許容量が定義されている。
許容量を超えるバイト数を扱う際に再確保される。
$ grep -nw capa string.c
...色々略...
717:       capa = (capa + 1) * 2;
782:       capa = (capa + 1) * 2;
とあるから、増えるときはおよそ2倍ずつ。
許容量が減ることはない気がする。
0486デフォルトの名無しさん
2006/11/02(木) 18:29:19初心者は str.gsub(/.../, "...") 形式を使ったらダメ。ゼッタイ。
str.gsub(/.../) { "..." } だけ使うこと。
0487デフォルトの名無しさん
2006/11/02(木) 18:36:230488デフォルトの名無しさん
2006/11/02(木) 18:44:220489デフォルトの名無しさん
2006/11/02(木) 18:51:230490デフォルトの名無しさん
2006/11/03(金) 02:46:42a = `command`
としたときに、標準出力しかaに入りません。
標準エラーを得るにはどうしたらよいか教えてください。
0491デフォルトの名無しさん
2006/11/03(金) 03:27:20念のために書いておくが、>>479 みたいなシェルスクリプトを
hoge.sh とか保存してシェルから実行しても意味が無いからな。
それだと Ruby スクリプトの時と同じでサブシェルのカレントが
変わるだけ。
例えば bash なら .bashrc に関数を定義してその関数経由で
Ruby スクリプトを実行すればおk。
foo(){
builtin cd "`hoge.rb`"
}
>>490
a=`command 2>&1`
標準エラーだけ欲しいなら
a=`command 2>&1 1>/dev/null`
csh系は知らん。
0492490
2006/11/03(金) 03:39:350493デフォルトの名無しさん
2006/11/03(金) 06:18:35require "open3"
a = nil
Open3.popen3("command"){|stdin, stdout, stderr|
a = stderr.read
}
なんてのも。
これならシェルには依存しない。プラットフォームには依存するが。
0494デフォルトの名無しさん
2006/11/03(金) 13:18:34is
a
pen
先頭のフィールドを削除して改行で区切って出力したいのですが
変数 a を使わずに出来ますか?
ruby 1.8.5 (2006-08-25) [i486-linux]
0495デフォルトの名無しさん
2006/11/03(金) 13:24:330496デフォルトの名無しさん
2006/11/03(金) 13:35:59ありがとうございます
-1 で配列の最後の要素になるんですね
0497デフォルトの名無しさん
2006/11/03(金) 23:22:33というハッシュがあるとき,Aが40%,Bが30%,Cが20%,Dが10%の確率になるように
ABCDを取り出したいのですがいい方法を教えてください
以下のような方法でも一応できたけどコストが大きすぎです
matched = false
while !matched
key = table.keys.sort_by{rand}.pop #キーをランダムに取得
if table[key] > rand #比較
#このときのkeyをつかう
matched = true
...
end
end
0498デフォルトの名無しさん
2006/11/03(金) 23:31:42C#を使おう
−−− というわけで、このスレ終了 −−−
0499デフォルトの名無しさん
2006/11/03(金) 23:40:540500デフォルトの名無しさん
2006/11/03(金) 23:46:52こんな感じでいいんじゃね?randが一様な乱数を返すのが前提だけど。
def get
table = {"A" => 0.4, "B" => 0.3, "C" => 0.2, "D" => 0.1}
ratio = rand
key = nil
table.each do |key, value|
if (ratio -= value) <= 0
break
end
end
key
end
result = Hash.new(0)
1000.times do
result[get] += 1
end
p result
0501デフォルトの名無しさん
2006/11/04(土) 00:03:12おお,ありがとうございます
0502デフォルトの名無しさん
2006/11/04(土) 13:21:22↓
引数を利用してサイトを巡る
↓
巡ったサイトを処理してデータ抽出
↓
抽出データを整形してブラウザに表示
というCGIスクリプトを書いてます。
途中の処理が遅くてユーザーにブラウザの中止ボタンなどを押される可能性があるので、
そういう時にはPStoreあたりでサーバにいくつかのデータを途中保存したいと思います。
「ブラウザ側からCGI動作を中止された」ことを検知する方法はありますか?
0503デフォルトの名無しさん
2006/11/04(土) 13:55:17その例ならデータの抽出整形までは完了するはずだからその後適当に保存なり何なりすれ
0504デフォルトの名無しさん
2006/11/04(土) 23:50:01例えば、a=0011;b= 0001;のときc=a+bとするとc=0100となるようにしたいのですが、
0baなどとしてもダメだし、String#%メソッドもうまい使い方がわかりません。
0505デフォルトの名無しさん
2006/11/05(日) 00:18:00"0b0100".to_i(2)
0506デフォルトの名無しさん
2006/11/05(日) 14:55:23よく考えたらインスタンスを1回しか作らないので。
module Hoge
def data
return 'hello'
end
def hello
puts data
end
module_function :hello
end
Hoge::hello
でも
undefined local variable or method `data' for Hoge:Module (NameError)
とか怒られます。…なんで?
0507デフォルトの名無しさん
2006/11/05(日) 15:09:11そんなんいちいち気にするな禿げるぞ
添削に出すのでもない限りクラスで作っとけ
0508デフォルトの名無しさん
2006/11/05(日) 15:39:150509デフォルトの名無しさん
2006/11/05(日) 17:51:55>undefined local variable or method `data' for Hoge:Module (NameError)
>とか怒られます。…なんで?
Hoge::hello() には、dataというローカル変数もないし、data()というメソッドも定義されていない。
Hoge::hello()はクラスメソッドだけどHoge#data()はインスタンスメソッドだから、前者から後者は見えない。
module_function :data
を追加すればいいのかな。あるいは
module Hoge
module_function
def data; return 'hello'; end
def hello; puts data; end
end
0510デフォルトの名無しさん
2006/11/05(日) 17:55:45> よく考えたらインスタンスを1回しか作らないので。
特異メソッドにでもしとけ。
class << (Hoge = Object.new)
def data; return 'hello'; end
def hello; puts data; end
end
Hoge.hello
0511デフォルトの名無しさん
2006/11/05(日) 19:02:18class なんとか って書くとまとまりになって
メソッド定義でいちいち def なんとか.hoge と書かないといけなくて面倒だけど
a=なんとか.new と最初に実行するように俺の中で決めておくと
def hoge と書いても動くようになるので書きやすくて便利とかそういう程度の認識しかない
0512デフォルトの名無しさん
2006/11/06(月) 08:46:16入力内容を表示する確認画面を作っているんですが、
hoge_index.rhtml
------------
<%= text_field "account", "name" %>
------------
hoge_controller.rbにて
------------
def confirm
@account = @params
end
---------------
hoge_confirm.rhtmlにて
------------
<%= @account['name'] %>
---------------
としてindexよりconfirmへ遷移した場合
indexページにて入力したnameの内容が表示されません。
@inputのみをタグ内部に記述すると@params全てが列挙されます。
参照の仕方を間違っているのか、何か根本的に間違ってるのでしょうか?
0513デフォルトの名無しさん
2006/11/06(月) 12:25:45クッキーを書き込む場合以下の様なコードで実現出来るとマニュアルに書いてあったのですが
ブラウザのクッキーファイルに全然書き込まれません… どうしてでしょう?
cookie = CGI::Cookie::new({'name' => 'name', 'value' => 'TEST', 'expires' => Time.now + 60 * 60 * 24 * 10})
cgi = CGI.new
cgi.out("cookie" => cookie){ "string" }
0514デフォルトの名無しさん
2006/11/06(月) 22:39:23それの前に Content-type:text/html を出力してしまってるに3ガバス
クッキーはヘッダですので最初に送って下さい
0516デフォルトの名無しさん
2006/11/07(火) 04:14:59Log4jみたいにLoggerの継承関係があって、Hoge::PiyoのLoggerの設定をしたら
logger=Log4r::Logger["Hoge::Piyo::Foo::Bar"]でHoge::PiyoのLoggerが取れると思ったのですが・・・
http://log4r.sourceforge.net/rdoc/files/log4r/logger_rb.html
Log4rのよい解説サイトってないですか?
0517デフォルトの名無しさん
2006/11/07(火) 07:00:03log4rはしらんけど、loggerというライブラリが標準添付されているのでそちらではどうでしょうか。
http://jp.rubyist.net/magazine/?0008-BundledLibraries
http://www.ruby-lang.org/ja/man/?cmd=view;name=Logger
0518デフォルトの名無しさん
2006/11/07(火) 11:38:04サーバーを起動するときに
ruby script\server
のようにいちいちプロンプトに入力せずに
サーバーを立ち上げるよい方法はありますか?
0519デフォルトの名無しさん
2006/11/07(火) 12:16:38例外のメッセージと同じような感じで、任意のオブジェクトを持ち出すことはできますか?
def main
begin
action1
action2 # メソッドのすげえ深部でエラーErrorAtAct2が起こる
action3
rescue ErrorAtAct2
# 「action2深部でエラーを起こしたときのハッシュデータを利用して別の処理をしてエラー回復」
end
end
ということをしたいです。
例外を起こしたメソッドの中でならハッシュデータにアクセスはできるんですが、
できればここのmainメソッドでまとめてエラー回復処理を書きたいです。
例外メッセージにハッシュを出力するとハッシュへの復元がなんだか面倒です。
0520デフォルトの名無しさん
2006/11/07(火) 20:07:59例外オブジェクトにハッシュを持たせればいいんじゃね。
class ErrorAtAct2 < StandardError
attr_reader :data
def initalize(data)
@data = data
end
end
def action1
h = {:a => 1 raise Error
0521デフォルトの名無しさん
2006/11/07(火) 20:09:42ごめん。途中で送って島田。
def action1
h = {:a => 1}
if エラー?
raise ErrorAtAct2.new(h)
end
end
def main
begin
action1
action2 # メソッドのすげえ深部でエラーErrorAtAct2が起こる
action3
rescue ErrorAtAct2 => e
# 「action2深部でエラーを起こしたときのハッシュデータを利用して別の処理をしてエラー回復」
p e.data
end
end
0522デフォルトの名無しさん
2006/11/07(火) 20:40:26↓こっちで聞いた方がよいかも。
【Agile】Ruby on rails相談所 part2【DRY】
http://pc8.2ch.net/test/read.cgi/php/1151254378/
こっちも人いないけど。
0524デフォルトの名無しさん
2006/11/09(木) 00:08:35シェルを介さないsystemでコマンドを実行しているんですけど、
コマンドの実行結果(stdout, err両方)を文字列で取得したいんだけどどうすればいいんですか。
0525デフォルトの名無しさん
2006/11/09(木) 00:23:11open3かな?
http://www.ruby-lang.org/ja/man/?cmd=view;name=open3
0526デフォルトの名無しさん
2006/11/09(木) 01:21:27環境かいてませんでした。すんません。
mswin32なんでopen3だとfork がNotImplementedErrorになりました。
でもそこからリンクをはってあるpopen4だといけました。
ありがとうございます。
0527513
2006/11/09(木) 07:23:20CGI#out でクッキーを出力するやり方はわかったのですが、
例えばoutのブロックの中では文字列しか出力出来ませんよね?
途中で色々処理したい場合なんかはどうやればよいのでしょうか?
これはもちろんエラーですが、以下の様な感じの場合です。
cgi.out("cookie" => cookie){
(0..4).each{|i|
print i + "\n"
}
}
0528デフォルトの名無しさん
2006/11/09(木) 08:33:56cgi=CGI.newとしたとして、具体的に何が作られるんだかさっぱりです
cgi1.paramsとcgi2.paramsの違いあるのかとか
cgi1.outとcgi2.outが同じページになるのかとか
0529デフォルトの名無しさん
2006/11/09(木) 09:19:12CGIってSingletonだとずっと思っていたが、そうじゃないのね
0530デフォルトの名無しさん
2006/11/09(木) 10:50:17…何度newしても最初のインスタンス1個だけが便利な感じで返ってくるような再利用構造?
うん、そうだね、そうあるべきだと便利だけど、cgi.rbは微妙にそのようにはなってないな。
#!/usr/bin/ruby -Ke
require 'cgi'
cgi1=CGI.new
cgi1.out {"cgi1:#{cgi1.params}<br>"}
cgi2=CGI.new
cgi2.out{"cgi2:#{cgi2.params}<br>"}
http://oreserver/test.cgi?hoge
cgi1:hoge
Content-Type: text/html Content-Length: 13 cgi2:hoge
cgi.outをCGI.newしたメソッド以外でも使うのなら
作ったcgiインスタンスを引数とかで連れて行くしかないな
0531513
2006/11/09(木) 12:41:410532513
2006/11/09(木) 13:36:42cgi.headerでやればいいと思ったのですが
これだと食べてくれません…
何方か助言を。
0533デフォルトの名無しさん
2006/11/09(木) 13:50:56インスタンス変数をkeyに、そのインスタンスのアドレス(ポインタ?)をvalueに持つhashを
作成したいのですが、アドレスをどういう形で得るのかが分かりません
簡単な質問かもしれませんがよろしくお願いします
館今日はWinXPでrubyのヴァージョンは1.8.5です
0534デフォルトの名無しさん
2006/11/09(木) 14:24:380535デフォルトの名無しさん
2006/11/09(木) 14:35:21同じページって言う意味がよくわからんのだが、CGIって簡単に言えば(主語はCGI)
・リクエストのたびにプロセスが起動され
・標準入力とか環境変数から入力を受け取って
・結果を標準出力に吐き出すだけ
じゃないのか。
試しに、ライブラリを使わずに、環境変数からパラメタ取得して、標準出力に結果を吐いてみればいい。
参考:ttp://www.tohoho-web.com/wwwcgi3.htm
わかりにくいのは別のところだと思うよ。
そもそも仕組みがわかってないと、Webプログラムはわかりづらいし書きづらい。
わかってても、ステートレスだとかHTMLも書かなきゃならんとか約束事が多いとかで
素のCGIは書いてて全然面白くない。皆さんフレームワーク使ってくださいと言いたい。
>>527
Cookieを複数出力したいなら例はマニュアルに書いてある。
ttp://www.ruby-lang.org/ja/man/?cmd=view;name=cgi#class.20CGI.3a.3aCookie
HTMLマニュアルを手元に置いておこう。
0536デフォルトの名無しさん
2006/11/09(木) 14:50:550537513
2006/11/09(木) 15:22:44いや、クッキーを複数出力したいんじゃないんです。
それはもう出来てるんです。
自分がわからないのは、cgi.outでクッキーを出力する場合に
cgi.outのブロックでHTMLを書き込む訳ですが
その場合に、以下の様な処理がしたいんです。でもこのコードでは最初のブロックの中だけしか出力されません…
cgi.out("cookie" => cookie){
"<html><body>" #html出力
}
(0..3).each{|i| #通常の処理
print i + '<br>'
}
cgi.out("cookie" => cookie){
"</body></html>" #html出力
}
cgi.out("cookie" => cookie){ #これはもちろんOK
"<html><body>test</body></html>"
}
要するに、htmlを一気に書き出すのではなくて
途中にプログラムの処理を挟みたいんです。
根本的に何か勘違いしているかもしれないんですが…
0538513
2006/11/09(木) 15:25:52cgi.out({"charset" => "shift_jis"}){…}
こうしてました。
0539デフォルトの名無しさん
2006/11/09(木) 16:27:39文字列str が、たとえば正規表現の /x/ か /y/ か /z/ に引っかかるなら何かしようと思い
if (str =~ /x/ or /y/ or /z/) then
と書きました。
でも肝心なときに動作が変なので試したら
irb> ("abcde" =~ /x/ or /y/ or /z/)
=> /y/
とか言われました。
なんでここで/y/ですか?
0540デフォルトの名無しさん
2006/11/09(木) 16:29:49釣りか?
>>514,515
これで了解したんじゃなかったのか?
マニュアルのURLを提示したんだから一通り読みなさい。
すごく分かり易いとは言えないが必要十分な情報が書いてある。
だいたい何を参考に作業してるんだy。
0541デフォルトの名無しさん
2006/11/09(木) 16:40:37ページってのはあれだ、たぶん
「クライアントからGETとかPOSTとか受け取って解釈してクライアントに出力結果渡す」
という一連の処理が「1ページ」ぶんなんだろう。1画面遷移とゆーか。
だから、cgi2=CGI.newとかが成功してしまうと、
「これって他のメソッドで作ったcgiインスタンスとどこが違うんだ?」と悩みの種に。
CGI#paramsはARGVを整理してくれるだけのメソッド
CGI#outはContent-Type:text/html\n\nを前につけてくれるだけのputs
と割り切ると気楽だと思う。
0542533
2006/11/09(木) 16:47:16では複数のインスタンスのなかから、
値がインスタンス変数と一致するようなインスタンスを探し出すためには
どのような手段を取ればよいのでしょうか?
0543デフォルトの名無しさん
2006/11/09(木) 16:57:50普通に使うぶんには代入でオブジェクトがコピーされることはない
参照が増えるだけで、メモリ上の実位置は動かない
0544デフォルトの名無しさん
2006/11/09(木) 17:01:490545513
2006/11/09(木) 17:10:53いや釣りじゃないです…
出力の途中に処理を挟みたい場合はどうするのかが知りたいんです。
↓こういうのって出来ないですよね?
cgi.out().out("cookie" => cookie){
"test"
}
print 'test2' #ここが出力されないから…
■ このスレッドは過去ログ倉庫に格納されています