アプリ版:「スタンプのみでお礼する」機能のリリースについて

こちらのサイトを参考にさせていただきました.
http://www.namaraii.com/rubytips/?%A5%D5%A5%A1%A …

やりたいことはファイルにアクセスして2行目,3行目の文字列をとってくることです.

===foo===
hoge
hige
foobar

File::open("foo") {|content|
 puts content.readlines[1]
 puts content.readlines[2]
}

このようなプログラムだと,
hige
nil
となります.ですが,以下のように分割するとうまくいきます.
File::open("foo") {|content|
 puts content.readlines[1]
}
File::open("foo") {|content|
 puts content.readlines[2]
}
hige
foobar

できればopenは一回だけで済ませたいのですが可能でしょうか?
Ruby初心者なのでくだらない質問かもしれませんが,ご教授ねがいます.

A 回答 (4件)

No3です。



>Rubyのみ初心者です.

よかった。

>>確認2:readlinesというメソッドはどういう機能を持ったメソッドだと思っていますか?

>ファイルの内容が一行ずつ入った配列だと思ってます

ファイルを行の配列のようにアクセスできるメソッドと思っているのなら間違いです。
ファイルから全データを読み込んで、それを配列の形で返すメソッドです。したがって、呼び出したことで、該当ファイルのファイルポインタ(ファイル中で次に読み取る文字位置)は末尾のEOFの所に行ってしまいます。二回目の呼び出しで、EOFに達したファイルを再度読むことになるので空が返ります。具体的には配列なので [] が返ります。

他の方がお書きのように、呼び出し結果の配列オブジェクトを保持しておいて、以降はそれをつかうといいです。
    • good
    • 0
この回答へのお礼

おお!
なるほど,どうりで2回目はnilになるわけですね
ありがとうございました.

お礼日時:2010/01/04 21:07

確認1:Rubyの初心者とお書きですが、他の言語でのこういうプログラミング経験があって、Rubyのみ初心者なのか、あるいは、プログラミングそのものの初心者なのかによって、説明のポイントが異なりますが、どちらでしょうか?



後者だとすると、かなり説明が大変です。

確認2:readlinesというメソッドはどういう機能を持ったメソッドだと思っていますか?

この回答への補足

>確認1:Rubyの初心者とお書きですが、他の言語でのこういうプログラミング経験があって、Rubyのみ初心者なのか、あるいは、プログラミングそのものの初心者なのかによって、説明のポイントが異なりますが、どちらでしょうか?

Rubyのみ初心者です.

>確認2:readlinesというメソッドはどういう機能を持ったメソッドだと思っていますか?

ファイルの内容が一行ずつ入った配列だと思ってます.

補足日時:2010/01/03 21:32
    • good
    • 0

content.readlines でファイルの内容が丸ごと入った配列になっているので、


普通の配列で二番目と三番目を取るにはどうすればいいかと考えてみてはどうでしょう?
あ、そう考えちゃっているから

File::open("foo") {|content|
 puts content.readlines[1]
 puts content.readlines[2]
}

としちゃったんですね。
File::open("foo") {|content|
 v = content.readlines
puts v[1]
puts v[2]
}
と同じだろうと考えちゃったのかもしれませんが違います。
なぜ違うのかはここでは説明しませんが、考えて分からないようなら補足に書いてください。

二つ目のように一時変数を作りたくないというのであれば#1の方の回答の他にも
こう言ったものが考えられます。

File.open('foo').each_with_index { |line, index|
puts line if index == 1 || index == 2
}

puts((File.open('foo').readlines)[1..2])

open("foo") {|file|
puts file.readlines[1..2]
}

open("foo") {|file|
puts file.readlines.values_at(1, 2)
}

お好みでどうぞ。

この回答への補足

遅くなって済みません,

わざわざ例を書いてくださってありがとうございます.

>なぜ違うのかはここでは説明しませんが、考えて分からないようなら補足に書いてください。
すみません,まったく違いがわからないです.

書いて下さった例でも,結局readlines[1]という風にアクセスしてるんじゃないの?と疑問に思ってしまいます.

補足日時:2010/01/01 22:23
    • good
    • 0

案1) open( 'foo' ) do |fh|


a = fh.readlines; p a[1]; p a[2];
end

案2) open( 'foo' ) do |fh|
lino = 0;
while fh.gets
lino += 1; p $_ if lino == 2 || lino == 3;
break if lino >= 3;
end
end
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!