gotagota日記

「面白きことは良きことなり」

『たのしいruby 第4版』第17章 IOクラス

第17章 IOクラス

模範解答はこちら

(1)

問題

テキストファイルからデータを読み込んで次の処理を行うスクリプトを作成しろ、という問題です。

私的解答
Twinkle, twinkle, little star,
How I wonder what you are!
Up above the world so high,
Like a diamond in the sky.
Twinkle, twinkle, little star,
How I wonder what you are!
When the blazing sun is gone,
When he nothing shines upon.
Then you show your little light,
Twinkle, twinkle, all the night.
Twinkle, twinkle, little star,
How I wonder what you are!
file = File.read('twinkle.txt')

# (a) 行数を数える
file.each_line do |line|
  printf("%3d %s", file.lineno, line)
end

# (b) 単語数を数える
ary = file.split(/\s+/)
p ary.size

# (c) 文字数を数える
ary = []
file.each_char { |ch| ary << ch }
p ary.size

模範解答とは趣がだいぶ違いますが(笑)
(a)では、 each_line メソッド使いつつ、printf メソッド用いて行頭に行番号を付しています。
(b)では、配列に変換して size メソッドを使いました。
(c)ですが、これだと空白も一文字としてカウントしてしまうので、改善が必要か・・・と思ったのですが、模範解答もほぼ変わらなさそうなのでいいのか???

(2)

問題

テキストファイルからデータを読み込んで次の条件に従って上書きするスクリプトを作成しろ、という問題です。

私的解答

file = File.read('twinkle.txt')

# (a) 行を逆順に並べ替える
file2 = file.dup
ary = []
file2.each_line { |line| ary << line }
puts ary.reverse

# (b) 最初の一行だけを残して残りを削除
file2 = file.dup
ary = []
file2.each_line { |line| ary << line }
ary.delete_at(0)
p ary

# (c) 最後の一行だけを残して残りを削除
file2 = file.dup
ary = []
file2.each_line do |line|
  ary << line
end
ary.delete_at(-1)
p ary

まず、元のテキストデータを本当に上書きするといろいろめんどくさいので、 dup メソッドでメモリ上にコピーしました。
(a)では、単純に reverse メソッドと用います。
(b)では、delete_at メソッドで一行目を指定して削除します。
(c)では、(b)と同じように delete_at メソッドを用い引数に -1 を指定して最終行だけ削除します。

(3)

問題

Unixで使われる tail コマンドと似たことができるメソッド tail を定義しろ、という問題です。

私的解答
def tail(lineNum, fileName)
  ary = []
  File.read(fileName).each_line { |line| ary << line }
  return ary[-lineNum..-1]
end
puts tail(3, 'twinkle.txt')

行ごとに配列に入れてから、ary[-lineNum..-1] で最終行から数えて指定行数分だけ指定しています。