你已經學過了 `STDIN.gets` 和 `ARGV`,這些是你開始學習讀取檔案的必備基礎。你可能需要多多實驗才能明白它的運作原理,所以你要細心練習,並且仔細檢查結果。處理檔案需要非常仔細,如果不仔細的話,你可能會把有用的檔案弄壞或者清空。導致前功盡棄。
這節練習涉及到寫兩個檔案。一個正常的 `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」在程式碼不是一個好主意,這些資訊應該是使用者輸入的才對。如果我們碰到其他檔案要處理,寫死的檔名就會給你帶來麻煩了。解決方案是使用 `ARGV` 和 `STDIN.gets` 來從使用者端獲取資訊,從而知道哪些檔案該被處理。
~~~
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. 讓你的腳本針對 `txt` 和 `txt_again` 變數執行一下 `close()`,處理完檔案後你需要將其關閉,這是很重要的一點。
- 笨方法更简单
- 习题 0: 准备工作
- 习题 1: 第一个程式
- 习题 2: 注释和井号
- 习题 3: 数字和数学计算
- 习题 4: 变数(variable)和命名
- 习题 5: 更多的变数和印出
- 习题 6: 字串(string)和文字
- 习题 7: 更多印出
- 习题 8: 印出,印出
- 习题 9: 印出,印出,印出
- 习题 10: 那是什么?
- 习题 11: 提问
- 习题 12: 模组 (Module)
- 习题 13: 参数、解包、参数
- 习题 14: 提示和传递
- 习题 15: 读取档案
- 习题 16: 读写档案
- 习题 17: 更多的档案操作
- 习题 18: 命名、变数、程式码、函式
- 习题 19: 函式和变数
- 习题 20: 函式和档案
- 习题 21: 函式可以传回东西
- 习题 22: 到现在你学到了哪些东西?
- 习题 23: 阅读一些程式码
- 习题 24: 更多练习
- 习题 25: 更多更多的练习
- 习题 26: 恭喜你,现在来考试了!
- 习题 27: 记住逻辑关系
- 习题 28: 布林(Boolean)表示式练习
- 习题 29: 如果(if)
- 习题 30: Else 和 If
- 习题 31: 做出决定
- 习题 32: 回圈和阵列
- 习题 33: While 回圈
- 习题 34: 存取阵列里的元素
- 习题 35: 分支 (Branches) 和函式 (Functions)
- 习题 36: 设计和测试
- 习题 37: 复习各种符号
- 习题 38: 阅读程式码
- 习题 39: 阵列的操作
- 习题 40: Hash, 可爱的 Hash
- 习题 41: 来自 Percal 25 号行星的哥顿人(Gothons)
- 习题 42: 物以类聚
- 习题 43: 你来制作一个游戏
- 习题 44: 评估你的游戏
- 习题 45: 物件、类和从属关系
- 习题 46: 一个专案骨架
- 习题 47: 自动化测试
- 习题 48: 更进阶的使用者输入
- 习题 49: 创造句子
- 习题 50: 你的第一个网站
- 习题 51: 从浏览器中取得输入
- 习题 52: 创造你的网页游戏
- 下一步
- 一个老程式设计师的建议