鑑於這種輸入文件,存儲爲 「test.txt的」:
test
test
test
testing
test
和此示例代碼:
def remove_line(line_to_remove)
File.foreach("test.txt").with_index do |line, line_num|
line.gsub!(/[\r\n]+$/, '')
if line == line_to_remove
puts "removed successfully"
else
puts line
end
end
end
您可以成功運行:
remove_line('testing')
,並得到如下的輸出:
test
test
test
removed successfully
test
函數採用行刪除的內容,並打開文件「行由行」的時尚。這是慣用的Ruby,並且應該優於「混淆」文件,正如在SO question的接受答案中所解釋的那樣。
一旦我們有了一條線,就有必要去掉它的線尾。由於我們不知道將要運行哪個平臺(或創建文本文件),因此我們使用正則表達式來查找所有已知行結束字符('\ r \ n'是Windows'\ n'是Linux/Unix/Mac OS X,'\ r'是Mac Classic)。
然後我們檢查一下該行是否與我們想要刪除的行相匹配。如果匹配,我們從輸出中省略它,而是打印它已被「成功移除」;否則,我們輸出不匹配的行。
這符合原始設計意圖,但是,有很多事情要做,以改善設計,並使整體更有用的功能。那麼,爲什麼不繼續做呢?
首先,我們將使函數以文件名作爲參數。這將從foreach
呼叫中移除硬編碼的"test.txt"
文件名。這將使這種變化發生了:
def remove_line(filename, line_to_remove)
File.foreach(filename).with_index do |line, line_num|
line.gsub!(/[\r\n]+$/, '')
if line == line_to_remove
puts "removed successfully"
else
puts line
end
end
end
可以成功運行這種方式,它會產生完全相同的輸出:
remove_line("test.txt", "testing")
接下來,讓我們改變輸出是如何發生的,以及我們」我會用塊來做到這一點,因爲那是Ruby的方式。這裏的功能是什麼樣子與塊輸出:
def remove_line(filename, line_to_remove, &block)
proc = block_given? ? block : lambda {|s| puts s }
File.foreach(filename).with_index do |line, line_num|
line.gsub!(/[\r\n]+$/, '')
if line == line_to_remove
proc.call "removed successfully"
else
proc.call line
end
end
end
這是建立與可選塊參數,所以你可以把它完全像以前的版本,使其工作完全相同的方式,也可以用一個明確的塊來調用它並做一些很酷的事情。
remove_line("test.txt", "testing") {|s| puts "#{s} in your pants" }
而且具有童心的額外的緊要關頭,你會得到這樣的輸出:此運行它修改字符串調用puts
稍前打印行的例子
test in your pants
test in your pants
test in your pants
removed successfully in your pants
test in your pants
您現在有權力做有趣的事情,從其他有趣的事情建立起來。明智地使用它,並繼續這樣做Ruby的方式。
當你說'if line == line'你想做什麼?這總是會是事實。 – Nobita
@Nobita我認爲他是指它作爲例子,如果作爲參數給出的字符串等於文件中的行之一,重寫行等。 – 13aal