我不確定最佳策略是什麼。我有一個課程,我可以在文件系統中搜索特定模式的文件。我只想執行一次Find.find(「./」)。我將如何處理這:避免在Ruby中對Find.find(「./」)進行多次調用
def files_pattern(pattern)
Find.find("./") do |f|
if f.include? pattern
@fs << f
end
end
end
我不確定最佳策略是什麼。我有一個課程,我可以在文件系統中搜索特定模式的文件。我只想執行一次Find.find(「./」)。我將如何處理這:避免在Ruby中對Find.find(「./」)進行多次調用
def files_pattern(pattern)
Find.find("./") do |f|
if f.include? pattern
@fs << f
end
end
end
記住一個方法調用(通常是計算密集型)的結果,這樣你就不需要它在下一次重新計算是已知的作爲memoization所以你可能會想要閱讀更多關於這一點。
實現它的一種方式是,Ruby將使用將結果存儲在實例變量中的小封裝類。例如
class Finder
def initialize(pattern)
@pattern = pattern
end
def matches
@matches ||= find_matches
end
private
def find_matches
fs = []
Find.find("./") do |f|
if f.include? @pattern
fs << f
end
end
fs
end
end
然後你就可以這樣做:
irb(main):089:0> f = Finder.new 'xml'
=> #<Finder:0x2cfc568 @pattern="xml">
irb(main):090:0> f.matches
find_matches
=> ["./example.xml"]
irb(main):091:0> f.matches # won't result in call to find_matches
=> ["./example.xml"]
注:||=
操作執行只有在左側的變量不計算爲False分配。即@matches ||= find_matches
是@matches = @matches || find_matches
的簡寫,其中find_matches
將僅由於短路評估而被首次調用。有很多other questions在Stackoverflow上解釋它。
輕微的變化:你可以改變你的方法來返回所有文件列表,然後使用從Enumerable
如grep
和select
方法來對文件的同一列表進行多次搜尋。當然,這存在將整個文件列表保存在內存中的缺點。這裏雖然是一個例子:
def find_all
fs = []
Find.find("./") do |f|
fs << f
end
fs
end
,然後用它喜歡:
files = find_all
files.grep /\.xml/
files.select { |f| f.include? '.cpp' }
# etc
調用的方法怎麼樣system "find/-name #{my_pattern}"
如果您想要結果而不是僅僅輸出標準輸出,請使用返回標記。 – 2010-10-01 12:17:22
這在Windows中肯定會失敗,並且在任何其他可能沒有找到可用或採用相同參數的平臺中都會失敗。我只會作爲最後一項措施來做到這一點。 – Pablo 2010-10-01 12:34:23
我實際上在發佈後立即刪除了這個答案(但顯然它並沒有被刪除),但是在我第二次閱讀這個問題之後,還有更多的問題。 – 2010-10-01 14:33:25
如果我正確理解你的問題你要運行到Find.find結果分配給一個實例變量。您可以將現在的塊移至單獨的方法,並調用該方法僅返回與您的模式匹配的文件。
唯一的問題是,如果目錄包含很多文件,你在內存中保存一個大數組。
謝謝。我基本上錯過了將塊轉換回方法的觀點。 – poseid 2010-10-01 14:11:24
你能否澄清一下這個問題。你是什麼意思*只執行Find.find(「./」)一次*? – mikej 2010-10-01 12:32:58
我認爲提問者意味着緩存Find.find('./')的結果。 – Swanand 2010-10-01 12:46:04
@Swanand啊,謝謝!在這個基礎上我會有一個答案。 – mikej 2010-10-01 13:00:04