トップページ⇒tech
1001コメント364KB

Ruby初心者スレッドPart8

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2006/09/28(木) 15:28:59
プログラミング言語Rubyについての、初心者向けスレです。質問・要望・雑談などどうぞ。
関連スレや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を読め」でいいので、叩かない&怖がらせない。
 ・わけわかな質問にもエスパー発揮で。できれば質問の仕方を教えるぐらいで。
 ・自信がない回答ならその旨表明すること。誤った回答は初心者じゃ見抜けない。


宗教的な話題は禁止します。
0652デフォルトの名無しさん2006/11/13(月) 20:09:34
p "x/100".to_f
0.0

>>651
まあ、そういうことだろうな
「x/100」という5文字の文字列に対して to_f したらそりゃ 0.0 だ

というか明示的に小数を含んで計算すれば小数表示されるぞ
p 37.0/100
0.37

んで答えはこうか
x=37
p x/100.to_f
0.37
0653デフォルトの名無しさん2006/11/13(月) 20:20:47
>>652
ありがとうございます。無事できました。
でも、変数/変数*100.0でやったら少数表示されませんでした。0.0と表示されて一応少数か。
小数点第何位で区切ろうとしたら、やはりprintfを使わないといけませんよね。
ちょっと面倒ですね。
0654デフォルトの名無しさん2006/11/13(月) 20:59:24
あれ、printf("%3f",hensu)
みたいにやっても有効桁指定できない・・・
0655デフォルトの名無しさん2006/11/13(月) 21:11:25
while gets 文じゃ
引数を指定しないとプログラムがおかしくなりますが、エラーはでないんですね

この場合の例外処理はどうすればよいのでしょうか?
0656デフォルトの名無しさん2006/11/13(月) 21:13:24
%x.yf
x : 全体桁
y : xのうちの少数桁
0657デフォルトの名無しさん2006/11/13(月) 21:15:16
> type a.rb
puts '%03d' % 12.3456

> a.rb
012

> ruby -e "puts '%03d' % 12.3456"
d

>ruby -v
ruby 1.8.5 (2006-08-25) [i386-mswin32]

なんだこりゃ?
0658デフォルトの名無しさん2006/11/13(月) 21:17:07
>>655
この場合も何も、例外処理なんて begin rescueしかない。
while gets って、受け取った入力は何処に入れてるんだ?
0659デフォルトの名無しさん2006/11/13(月) 21:23:58
>>658
受け取った入力は、変数にいれてます
begin
while line = gets
.
.
.
rescue
puts ほにゃらら
end

みたいにやっても、引数なしで実行すると
改行された画面みたいにしかならなくてエラー名も何もでないのですが・・
0660デフォルトの名無しさん2006/11/13(月) 21:24:29
>>658
$_
0661デフォルトの名無しさん2006/11/13(月) 21:26:57
>>656-657
ありがとうございます。助かりました。
ついでにもうひとつとねがいしたいのですが、
printf("%3.1f",hensu,"\n")
34.1% みたいにしたいのですが、%はどこにいれればよいのでしょうか?
fのあとにスペースしていれたり、\をつけて文字としてあつかうようにしてみたのですが
無理でした。
0662デフォルトの名無しさん2006/11/13(月) 21:28:17
>>661
マニュアルくらい読め
その調子だとこの先もわからないことがあったら全部人に聞くだろ
0663デフォルトの名無しさん2006/11/13(月) 21:29:32
>>659

if ARGV.empty?
$stderr.puts "Error"
exit 1
end

while ...
0664デフォルトの名無しさん2006/11/13(月) 21:29:57
組み込み関数 gets のマニュアル見るとわかるんだが、
ただの gets は Perl のダイヤモンド演算子のように振舞う。
つまり、引数がないときは標準入力の内容を読む。

引数の有無で例外処理をさせたい場合には使用してはいけない。
0665デフォルトの名無しさん2006/11/13(月) 21:30:49
>>662
一応、rubyリファレンスマニュアルに目をとおしてるのですがよくわからなかったので・・・
何か例文集の本とか買ったほうがいいのかな
0666デフォルトの名無しさん2006/11/13(月) 21:33:04
>>665
http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=sprintf%A5%D5%A5%A9%A1%BC%A5%DE%A5%C3%A5%C8
0667デフォルトの名無しさん2006/11/13(月) 21:34:17
オンラインマニュアルのprintfの項には
> 引数の扱いの詳細については sprintfフォーマット を参照してください。
ときちんと誘導されてると思うんだが
0668デフォルトの名無しさん2006/11/13(月) 21:37:01
>>667
「引数の扱いの詳細」という日本語が、
初心者にとって良くないのかも。
0669デフォルトの名無しさん2006/11/13(月) 21:37:27
>>667
すみません。このx.y のようにするとは思わなかったので・・・
今再度確認したらやはりちょっとわかりにくいですね。

>>663
なぜ exit 1 なのでしょうか?
デフォルトでは0が終了ステータスと書いていましたが、
1というのはエラーで終了したということでしょうか?
0670デフォルトの名無しさん2006/11/13(月) 21:37:51
まあ、あのマニュアルはマニュアル慣れした人向けであることは常々感じてるんだが
ふつーの人はアレ読めないって
0671デフォルトの名無しさん2006/11/13(月) 21:43:30
>>670
というか、肝心なとこに限ってえっらいわかりにくいんだよな
どっか別の場所で知識つけてきて初めて高速に読み飛ばせるハイパーなマニュアル

>>669
終了ステータスの勉強するといい
Rubyどうこうではなく、コマンドの正常終了時は0で、異常終了時は0以外だ(時々守られてないが)
自分ひとりで使うぶんにはまったく気にしなくてもいいが、癖をつけておくと良
0672デフォルトの名無しさん2006/11/13(月) 21:46:28
>>671
ありがとうございました。
デフォルトが0なのは、正常終了したプログラムを別のプログラムに渡すためなのでしょうね。
1つの簡単なプログラムだと別にexitは指定しなくていいっぽいですね。
Cをちょっとかじったときは、EXIT_SUCCESS とか常につけるようにしていましたが。
06736612006/11/13(月) 21:47:46
すみません、
printf("%3.1f",hensu,"\n") の"%3.1f"の中に文字としての%をつけくわえるのは
可能なのでしょうか?
sprintfマニュアルみてもそれっぽいのがなんかなかったのですが・・・
0674デフォルトの名無しさん2006/11/13(月) 21:49:44
http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=sprintf%A5%D5%A5%A9%A1%BC%A5%DE%A5%C3%A5%C8

`%' 自身を出力するには `%%' とします。
06756612006/11/13(月) 21:50:39
>>674
あ、すみません。そういう意味だったんですか・・・
申し訳ありません。
0676デフォルトの名無しさん2006/11/13(月) 22:28:33
RubyとPerlプログラムでファイル中の文字カウントのスピードを比較していたのですが、
結果は、Perlのほうがはやいものでした。
プログラムの作り方によるのかもしれませんが、一般的にPerlのほうがはやいのでしょうか?

Rubyでは、hashつくってsplitとしてイテレーターつかってるから遅いのかな
0677デフォルトの名無しさん2006/11/13(月) 23:29:32
count.each{|key,value|
print "#{key}:\t"
}.print("\n").each{|value|
print "#{value}:\t"
}

key: key: key: key:
value: value: value: value: 
というように表示したいのですが、上記のようなプログラムでは
keyを全部出力したあとに改行されませんでした。間に改行をいれるにはどうすればよいのでしょうか?

count.each
printf "\n"
count.each

というようにわけずにかきたいのですが・・・
0678デフォルトの名無しさん2006/11/13(月) 23:33:07
それ以前に君はこのプログラムがどういう動作をしているのか理解できているのか
自分にとって理解しやすいように書くという気はないんか
0679デフォルトの名無しさん2006/11/14(火) 00:05:38
ブロックつきeachにブロックつきeachがくっついてる時点で俺は解読に自信がない
0680デフォルトの名無しさん2006/11/14(火) 00:32:39
>>679
printのところとったら動きましたよ
ただ改行がなかっただけで正確でした
0681デフォルトの名無しさん2006/11/14(火) 00:56:12
そのprint("\n")は何に対して呼び出してるつもりなんだ。
0682デフォルトの名無しさん2006/11/14(火) 00:58:09
>>681
プッ
初心者はこれだからwwww
その前の

each{|key,value|
print "#{key}:\t"
}

というブロックに決まってるじゃないか
0683デフォルトの名無しさん2006/11/14(火) 01:03:59
>>682
どんな動作になるかよくわからんな(w

というかここの部分でエラーとかは出んのか…?

irb> {'key'=>'value'}.each{|k,v| print k,v}.print "\n"
keyvalueNoMethodError: private method `print' called for {"key"=>"value"}:Hash

…。どうやって動いたんだ…?
0684デフォルトの名無しさん2006/11/14(火) 01:17:04
LinuxのWebサーバ上に載せるスクリプトで Win32APIって使えますか?
クライアント側はWindowsであることを想定してます。

Web上で入力したデータを Excel フォーマットに整形して取得したいのですが、、、
0685デフォルトの名無しさん2006/11/14(火) 02:05:39
Web上で入力したデータを取得してExcelフォーマットに変換しろ

あと、90パーセントくらいまでの要件は、Excelファイルをどうしようとかではなく

  ・タブ区切りかCSVでRubyが吐き出したものをユーザーにローカルに保存させてユーザーがExcelで読む

ことで用が済む
0686デフォルトの名無しさん2006/11/14(火) 08:29:12
site_rubyのsiteって何の略でしょうか??

Windowsで使ってるんですが、
C:\ruby\lib\ruby以下に、site_ruby, 1.8, gemsってなってます。
バージョンに寄らずに一定のライブラリが入ってるみたいですけど、
よく分かりません。
06876772006/11/14(火) 08:58:06
private method `print' called for {"key"=>value, "key"=>value, "key"=>value}:Hash (NoMethodError)
key: key: key: key: key: key:


このようなエラーになってしまいます。
どうすれば改行をいれられるのでしょうか?
0688デフォルトの名無しさん2006/11/14(火) 09:22:25
Hashのselfが返ってくるのでそこからprintは呼び出せないのでは…?
分けて書くのが見易いし良いと思うけど。
count.each{|k| print("#{k}:\t")}
printf "\n"
count.each{|v| print("#{v}:\t")}
0689デフォルトの名無しさん2006/11/14(火) 09:31:36
こうだったか。
count.each_key{|k| print("#{k}:\t")}
print("\n")
count.each_value{|v| print("#{v}:\t")}

というより、これに何の意味があるの?
count.each{|k,v| … }.each{|v| … }
06906772006/11/14(火) 09:41:41
>>689
ありがとうございます。
1行でかきたかったんですね。あと、できるのかというのも含めて。

思ってたのですが、#{k} こういうかっこでかこうのって面倒ですよね
なんか意外なんですが
0691デフォルトの名無しさん2006/11/14(火) 09:47:21
日記は別のところで書け。
0692デフォルトの名無しさん2006/11/14(火) 10:33:26
Rubyの質問かどうか分かりませんが・・・

大量のテキスト処理をするスクリプトにwxRubyでGUIをつけたところ、
終了までに物凄く時間がかかるようになってしまいました。(環境は
Winです)ところが、ウィンドウの上でマウスホイールをクルクルやると、
なぜか、時間がかなり短縮されます。

印刷のときにもこれをやると効くらしいのでWindowsの仕様なの
かもしれませんが、スクリプトの側でコントロールするとかって、
できないものでしょうか?
0693デフォルトの名無しさん2006/11/14(火) 11:18:52
ファイルの中から、何文字目から何文字目までを抽出するにはなんの関数をつかったらよいのでしょうか?
Cではsizeofを使っていたのですが。

何文字目からですか?
10000
何文字目までですか?
430000

みたいに段階をおっていきたいのですが
06946922006/11/14(火) 11:20:30
「マウスホイールで印刷が早くなる?」
http://d.hatena.ne.jp/softether/20060505
06956932006/11/14(火) 12:24:34
分かりやいうと

!title
私の数字は3です。
これからもよろしくお願いします。
また後で。

みたいなファイルがあったとして、この中の、!行は無視して
11文字めの「れ」から28文字目の「後」までの文字を抽出したい場合、
どうすればよいのでしょうか?
このように文字数が少ない場合だと、一度に全行を読み込んでも問題ないのでしょうが
行が多い場合だとやはり、全行読むのはやめたほうがよいですよね。
それも考えるとどう処理していけばいいのかがよくわからないです。
0696デフォルトの名無しさん2006/11/14(火) 13:07:27
こんな感じじゃね?

何文字目か記憶する変数をoffsetとして定義する(1で初期化)
それぞれの行をlineとして読み込む
    lineから改行文字を削除
    lineが!で始まっていたら次の行へ
    lineが何文字目から何文字目にあたるかoffsetから計算する
    20文字目から40文字目までなら最初から途中までが範囲内だから出力
    offsetにlineの文字数を足す

まあ、全行読み込めるならそのほうが楽だな。
0697デフォルトの名無しさん2006/11/14(火) 14:17:05
a = <STDIN>
b = <STDIN>

print "#{a}"
print "#{b}"

これじゃ、入力できないのですが何故なのでしょうか
0698デフォルトの名無しさん2006/11/14(火) 14:21:51
>>697
エラーは読め
英語だから読めないとかは無し
無理してでも読め


というかそれ以前の気もするが
どこか解説サイトあるいは入門書籍などを一通り読んで勉強してみることを強く推奨
0699デフォルトの名無しさん2006/11/14(火) 14:24:44
>>698
リファレンスと書籍よんだのですが、
C言語のscanfにあたるものがのってなかったのですが・・・

ARGVじゃちょっと違うし
0700デフォルトの名無しさん2006/11/14(火) 14:28:50
エラー読んでないと言われてる意味をわかってないみたいだな

./test.rb:1: syntax error
a=<STDIN>
  ^
./test.rb:2: syntax error

なぜRubyスクリプトでRubyの文法を無視するんだ?
0701デフォルトの名無しさん2006/11/14(火) 14:44:44
どこにSTDINの文法がかいてありますか?
書籍に書いてないし、リファレンスにもないので困っております
0702デフォルトの名無しさん2006/11/14(火) 14:47:52
<STDIN>

 < > ←これは何よ?
0703デフォルトの名無しさん2006/11/14(火) 14:54:06
ダイヤモンド演算子使いたいなら
periに池
0704デフォルトの名無しさん2006/11/14(火) 15:30:39
>>702
<>をつけないで最初やったら、エラーがでたので
つけてみたのですが、やはり無理でした
0705デフォルトの名無しさん2006/11/14(火) 15:41:15
2chのRubyユーザーコミュニティの真価が問われる瞬間がやってきたと感じる
0706デフォルトの名無しさん2006/11/14(火) 15:44:39
すみません、どうすればよいのでしょうか?
0707デフォルトの名無しさん2006/11/14(火) 15:59:50
1. 以下の文言を一日に3回唱える
 「RubyはPerlではない」

2. "ドットの前"のものがどんな種類のものなのか常に意識する

3. 『たのしいRuby』の第1部から第3部あたりを通して流し読みする

4. 単に「エラーが出ました」とか他人にとって意味不明なことを口にしない

5. $stdin.gets と書く
0708デフォルトの名無しさん2006/11/14(火) 16:09:49
学んだ上での間違いと何も知らない状態の間違いってけっこう見分けつくしな
明らかに後者だ

何も知らない者は自分で何かを作ることができないし
何も知らない者が一文字書く度に聞きなおすのに付き合うほどこのスレは暇じゃない
0709デフォルトの名無しさん2006/11/14(火) 16:18:20
scanf rubyでググったり、マニュアルを検索すると、いとも容易く見つかるscanf.rb
ttp://www.ruby-lang.org/ja/man/?cmd=view;name=scanf;em=scanf
0710デフォルトの名無しさん2006/11/14(火) 16:33:22
>>707
はい心がけます。
しかし、この本、stdin.getsという言葉は1回もでてこなかったのですが・・・
0711デフォルトの名無しさん2006/11/14(火) 16:42:02
>>710
だから何?
標準入力として$stdinは紹介されてるし、それがIOオブジェクトに属することもきちんと書いてある。
IOオブジェクトioから1行読み込むio.getsも解説があるだろ。

それでわからないならプログラミングにそもそも向かないからすっぱり諦めろ。
プログラミングに向かない人は一定数いるし、それは知能が低いことや人間としての欠陥を全く意味しない。
気にせず諦めろ。
0712デフォルトの名無しさん2006/11/14(火) 17:06:08
向いてないけどやりたいってのは止められんよ。
本人じゃないからどう考えてるか知らんが。

PerlにあるならRubyにも同じものがあるもんだっつー思いこみを捨てるとか、資料は読むだけじゃなくて意味を勉強しろとかは言いたい。
まあPerlで幸せなら無理してRubyを使う必要はないとも言えるが。
0713デフォルトの名無しさん2006/11/14(火) 17:22:06
>>712
711じゃないけど、「やりたい気持ちを止められない」ってのも大切な要素だよね。
本当に好きなら、多少頭が悪かろうが、効率悪いコードしか書けまいが
諦めずに続ける事が出来るもんね。

printf("Hello, World!\n");

初めてプログラム書いて、これ実行して何も感じないなら「向いてない」って事かもしれないね。
0714デフォルトの名無しさん2006/11/14(火) 17:41:52
while line = gets
line.chomp!
str = ""
str << line
end

print "#{str}"


これのどこが間違っていますか?
プログラム実行してもエラーが出ません。引数にファイルを指定しています。

あめんぼあかいな
あいうえお
きたちょうせん

みたいな中身ですが、それぞれの文字を結合できないのでうが・・・
0715デフォルトの名無しさん2006/11/14(火) 17:53:53
だから単体のgetsは区別めんどくさいから勉強中は使うなと

>>714
「変数のスコープ」について調べるといい
0716デフォルトの名無しさん2006/11/14(火) 18:09:23
while line = gets
p line
line.chomp!
str = ""
str << line
p str
end
print "#{str}"

-------------

"あめんぼあかいな\n"  ← p line
"あめんぼあかいな"   ← p str
"あいうえお\n"       ← p line
"あいうえお"        ← ここのstrが期待と違う
"きたちょうせん\n"
"きたちょうせん"
きたちょうせん

--------------

ということで、どうやらstrが毎回空になってる模様、と推測する。
で、原因は>>714の言うスコープ。しかも微妙な原因。
whileはスコープを作らないんで、一般的なスコープの問題ではないんだけど、やっぱスコープだ。
0717デフォルトの名無しさん2006/11/14(火) 18:43:29
こういうのも「スコープの問題」って言えるのか・・・
0718デフォルトの名無しさん2006/11/14(火) 18:49:01
スコープ…が上書きされ…スコープが不適切…かなあ
まあ、繰り返しの途中から始まってるのが問題だからスコープ…かなあ

「繰り返しの途中で毎回空文字列がセットされてるのが原因だぴょん」でよくね?という気はする
0719デフォルトの名無しさん2006/11/14(火) 18:56:00
>>718
いや、空文字列が一番の原因じゃないぜ
0720デフォルトの名無しさん2006/11/14(火) 19:10:09
同じスコープ内で起こっているのだから、スコープの問題ではない。
str への空文字列の代入を最初に1回だけ行えばよい。
0721デフォルトの名無しさん2006/11/14(火) 19:11:07
こういうのって合ってるんだからエラーがでないんだよな
初心者には意外な落とし穴なのかね
0722デフォルトの名無しさん2006/11/14(火) 19:26:56
str='' if str == nil
でも用が足りるわけだからね
別に str='' をwhileの「前」に出す必要はない

ブロックとスコープうんたらの問題と同じような解決法で
わかりやすく問題が解消されるのは事実だけど
0723デフォルトの名無しさん2006/11/14(火) 19:37:25
str = STDIN.read.gsub(/\n/m, "")
でどうだ!
0724デフォルトの名無しさん2006/11/14(火) 19:39:09
>>722
str ||= ''

# 流れを読まずに書いてみる
0725デフォルトの名無しさん2006/11/14(火) 19:44:05
>>724
その手の演算子嫌いなんだよね
読み下しにくいっていうか絶対半年後とかに書き間違う
0726デフォルトの名無しさん2006/11/14(火) 19:55:56
>>722 も修飾子じゃなければエラーになるし、
あまり初心者に勧められる方法じゃないと思うが。
0727デフォルトの名無しさん2006/11/14(火) 20:01:24
「ループの後でも使いたい変数はループの前にあらかじめ定義しておこうね!」
という啓蒙活動でよろしか

str = ""

while line = gets
line.chomp!
str << line
end

print "#{str}"
0728デフォルトの名無しさん2006/11/14(火) 20:36:30
Rubyって一番最初に学ぶ言語には向かないですよね…
他の言語がある程度分かってないと、理解し難い部分が沢山ある様な気がするし…
出来れば、JavaとかC++とか覚えた後に使うのがいい様な気がするけど。
0729デフォルトの名無しさん2006/11/14(火) 20:58:49
みなさんありがとうございました。
ようやくできてきたのですが、
X(start)文字目からY(stop)文字目の文字を取り出す方法を2通り考えてみたのですが
どちらのほうが負荷が少ないのでしょうか?

string = str.split(//e)[start..stop].to_s

while start <= stop
print "#{str[start-1].chr}"
start += 1
end
0730デフォルトの名無しさん2006/11/14(火) 21:06:11
str = s[start..stop]
0731デフォルトの名無しさん2006/11/14(火) 22:41:59
Rubyのブロック構文は,関数ポインタやデリゲートやラムダ式・高階関数を学んでからでないと理解が難しい気がする。
0732デフォルトの名無しさん2006/11/14(火) 23:20:50
array#push と array<<ってどっちが早いですか?
0733デフォルトの名無しさん2006/11/14(火) 23:23:34
>>732
require "benchmark"
0734デフォルトの名無しさん2006/11/14(火) 23:26:15
自力で確かめるのはいいことだ

>>731
ぶっちゃけどれも全く知らないがブロック構文は1週間も使ってれば覚えたぞ
0735デフォルトの名無しさん2006/11/14(火) 23:27:42
rb_define_method(rb_cArray, "<<", rb_ary_push, 1);
rb_define_method(rb_cArray, "push", rb_ary_push_m, -1);

rb_ary_push_m(int argc, VALUE *argv, VALUE ary)
{
while (argc--) {
rb_ary_push(ary, *argv++);
}
return ary;
}
0736デフォルトの名無しさん2006/11/14(火) 23:30:19
>>735
初心者ですがまったくわかりません。
* と int と VALUE が
0737デフォルトの名無しさん2006/11/15(水) 00:12:36
>736
これはrubyインタプリタプログラムそのもののソース。言語はC。
で735が何を云いたいのか憶測してみると

1. Array#<<の実装は rb_ary_push()関数
2. Array#pushの実装は rb_ary_push_m()関数
3. rb_ary_push_m()関数は内部でrb_ary_push()関数に仕事(の一部)を任せている
ゆえに: Array#<<の方が少し効率が良さそうなもんだ

か?
0738デフォルトの名無しさん2006/11/15(水) 00:23:21
>>729
分かりやすいほうを選ぼう。
速度やメモリ使用量は困ってから考えればいい。
0739デフォルトの名無しさん2006/11/15(水) 08:45:32
Ruby/Tkってどうやって勉強すればよいのでしょうか?
本がでてないと思うのですが
0740デフォルトの名無しさん2006/11/15(水) 08:47:26
あんなもん使うな
GUIが欲しければ他の言語使え
0741デフォルトの名無しさん2006/11/15(水) 08:52:33
一般論として << を使ったほうが早い

文字列連結も
str = str + 'hoge'
よりも
str << 'hoge'
のほうが早いしメモリも使わずに済む

ただ、<< は若干わかりにくいし
一般用途上は誤差レベルなので好きにやっていい
コンマ1秒の差が生死を分けるとかそういうチューニングが必要な人向け
0742デフォルトの名無しさん2006/11/15(水) 09:50:18
文字列(string)をファイルに書き込むにはどうしたらよいのでしょうか?

io = File.open(out, "w")
io.string ?
0743デフォルトの名無しさん2006/11/15(水) 09:53:11
File.open(out, "w"){|io| io.write string}
0744デフォルトの名無しさん2006/11/15(水) 10:01:09
>>742
FileクラスとIOクラスの関係は序盤の山場だ
何も考えずにドットでくっつけるだけで書いてると、ここで必ず手が止まる

ここがきちんと理解できれば他の場面でも応用が利く
(というか、よく知らないクラスでも普通に利用できるようになる)
頑張って踏ん張れ
0745デフォルトの名無しさん2006/11/15(水) 10:11:52
>741
String#+ と String#<< の違いとは別の話。

Array#push は複数の引数を取りうるが、 Array#<< は引数を1つしか取らない。
そこで Array#push は引数すべてについてループを使って Array#<< を呼び出
している。

だから引数が1つのときはループの初期化と終了チェックのぶんだけ遅い、っ
ていうくらいの差。
個人的には(青木さんもどこかで書いていたが) << は push なんだか concat
なんだか混乱するので push を使うことにしているが。

でも benchmark で調べてみたらけっこう差があるな。

require 'benchmark'
include Benchmark
puts CAPTION, measure { res = []; 100000.times {res.push('a')} }, measure { res = []; 100000.times { res << 'a' }}
user system total real
0.093750 0.000000 0.093750 ( 0.098360)
0.085938 0.000000 0.085938 ( 0.086664)
0746デフォルトの名無しさん2006/11/15(水) 10:17:10
>>743-744
なるほど。ありがとうございます。

しかし、File.open だとFileオブジェクトにopenしろといってるんですよね。
io = といったみたいな形にしないと
closeできないのでは?
IOクラスのサブクラスがFileだから、io=とかを指定しない場合でも、
io.closeで閉じられるということかな
io.writeのほうが{}ないにイテレータで入ってるから、io.writeで閉じられるのは分かりますが。
{}の外(後)にio.closeと書くとioがさしているのがわからないような・・・

それとも、io.closeとすると入出力のために開いていたもの全てを閉じるという意味なのでしょうか
0747デフォルトの名無しさん2006/11/15(水) 10:26:12
io=File.open(filename)
io.write(text)
io.close

FIle.open{|io|
io.write(text)
}

この2つは同じ動作をする
ioの"寿命"も1行目で生まれて3行目で死ぬという点で同じだ

というかどっかそのへんに解説書いてないか?
ブロックを利用するとcloseを明示的に書く必要がなくて便利ですとか何とか
0748デフォルトの名無しさん2006/11/15(水) 10:50:35
俺も初学者なんだけど、ちょっと認識が間違ってたかも…
ガベージコレクションが内部で働いた時、
例えばFileクラスのインスタンスってのは自動的にファイルをクローズしてくれますか?

f = File.open('file', 'r')
s = f.read
やはりここで明示的にcloseしなくてはダメ?

あとこの場合はどうなる??
s = File.read('file')
closeも一緒にやってくれる?
それとも次のread等の呼び出し時にチェックしてclose??
流石にこれはcloseも一緒なんでしょ?

そもそもC++みたいにデストラクタとか無いんで
ファイルのcloseってどうなってますか??
0749デフォルトの名無しさん2006/11/15(水) 10:58:47
GCがcloseするけど、

File を open したままにしておくようなコーディングは、C言語レベルでの誤動作
の原因となるため、あまり好ましくありません。きちんと明示的に close すること
が大切です。

だそうである。
0750デフォルトの名無しさん2006/11/15(水) 11:04:47
>>749
やっぱ、なるべく
File.open('file', 'r'){|f| s = f.read }
みたいに書いた方がいいみたいですね。

今まで散々ガベージコレクトがあると思って
File.open('file', 'w').write(s)
とか書きまくってたけど…
まぁこれも一応「重大な問題」は無いんですよね?
0751デフォルトの名無しさん2006/11/15(水) 11:49:01
>>750
それはそうだが、Rubyの最大のボトルネックはGCだし、過度に
頼らないほうがいいと思われる。マーク&スイープっていう古い
アルゴリズムだから。
ジェネリックなGCにするとかいう話も出てるけど。
■ このスレッドは過去ログ倉庫に格納されています