Learn Ruby The Hard Way

笨方法學 Ruby

習題 15: 讀取檔案

你已經學過了 STDIN.getsARGV,這些是你開始學習讀取檔案的必備基礎。你可能需要多多實驗才能明白它的運作原理,所以你要細心練習,並且仔細檢查結果。處理檔案需要非常仔細,如果不仔細的話,你可能會把有用的檔案弄壞或者清空。導致前功盡棄。

這節練習涉及到寫兩個檔案。一個正常的 ex15.rb 文件,另外一個是 ex15_sample.txt,第二個文件並不是腳本,而是供你的腳本讀取的文字檔案。以下是後者的內容:

This is stuff I typed into a file.
It is really cool stuff.
Lots and lots of fun to have in here.

我們要做的是把該檔案用我們的腳本「打開(open)」,然後印出來。然而把檔名 ex15_sample.txt 「寫死(Hard Coding」在程式碼不是一個好主意,這些資訊應該是使用者輸入的才對。如果我們碰到其他檔案要處理,寫死的檔名就會給你帶來麻煩了。解決方案是使用 ARGVSTDIN.gets 來從使用者端獲取資訊,從而知道哪些檔案該被處理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
filename = ARGV.first

prompt = "> "
txt = File.open(filename)

puts "Here's your file: #{filename}"
puts txt.read()

puts "Type the filename again:"
print prompt
file_again = STDIN.gets.chomp()

txt_again = File.open(file_again)

puts txt_again.read()

這個腳本中有一些新奇的玩意,我們來快速地過一遍:

程式碼的 1-3 行使用 ARGV 來獲取檔名,這個你已經熟悉了。接下來第 4 行我們使用一個新的命令 File.open。現在請在命令列執行 ri File.open 來讀讀它的說明。注意到這多像你的腳本,它接收一個參數,並且傳回一個值,你可以將這個值賦予一個變數。這就是你打開檔案的過程。

第 6 行我們印出了一小行,但在第 7 行我們看到了新奇的東西。我們在 txt 上呼叫了一個函式。你從 open 獲得的東西是一個 file (檔案),檔案本身也支援一些命令。它接受命令的方式是使用句點 . (dot or period),緊跟著你的命令,然後參數。就像 File.open 做的事一樣。差別是:當你說 txt.read() 時,你的意思其實是:「嘿 txt!執行你的 read 命令,無需任何參數!」

腳本剩下的部份基本差不多,不過我就把剩下的分析作為加分習題留給你自己了。

你應該看到的結果

我的腳本叫 “ex15_sample.txt”,以下是執行結果:

$ ruby ex15.rb ex15_sample.txt 
Here's your file 'ex15_sample.txt':
This is stuff I typed into a file.
It is really cool stuff.
Lots and lots of fun to have in here.

I'll also ask you to type it again:
> ex15_sample.txt
This is stuff I typed into a file.
It is really cool stuff.
Lots and lots of fun to have in here.

$

加分習題

這節的難度跨越有點大,所以你要儘量做好這節加分習題,然後再繼續後面的章節。

  1. 在每一行的上面用注釋說明這一行的用途。
  2. 如果你不確定答案,就問別人,或者是上網搜尋。大部分時候,只要搜尋「ruby 你要搜尋的東西」,就能得到你要的答案。比如搜尋一下「ruby file.open」。
  3. 我使用了「命令」這個詞,不過實際上他們的名字是「函式(function)」和「方法(method)」。上網搜尋一下這兩者的意義和區別。看不懂也沒關係,迷失在其他程式設計師的知識海洋裡是很正常的一件事。
  4. 刪掉 9-15 行使用到 STDIN.gets 的部份,再執行一次腳本。
  5. 只用 STDIN.gets 撰寫這個腳本,想想哪種得到檔名的方法更好,以及為什麼。
  6. 執行 ri File 然後往下捲動直到看見 read() 命令(函式/方法)。看到很多其他的命令了吧。你可以玩其他試試。
  7. 再次啟動 IRB,然後在裡面使用 File.open 打開一個文件,這種 open 和 read 的方法也值得一學。
  8. 讓你的腳本針對 txttxt_again 變數執行一下 close(),處理完檔案後你需要將其關閉,這是很重要的一點。