我不确定这是什么最好的策略。我有一个类,我可以在文件系统中搜索某种模式的文件。我只想执行一次Find.find(“./”)。我该如何处理:
def files_pattern(pattern)
Find.find("./") do |f|
if f.include? pattern
@fs << f
end
end
end
答案 0 :(得分:4)
记住方法调用的(通常是计算密集型)结果,这样你下次调用方法时就不需要重新计算它了,所以你可能会被称为 memoization 想要了解更多相关信息。
实现Ruby的一种方法是使用一个将结果存储在实例变量中的小包装类。 e.g。
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
仅在第一次由于短路评估而被调用。在Stackoverflow上有很多other questions解释它。
轻微变化:您可以更改方法以返回所有文件的列表,然后使用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
答案 1 :(得分:1)
如果我正确理解您的问题,您希望运行Find.find将结果分配给实例变量。您可以将现在的块移动到单独的方法,并调用它以仅返回与您的模式匹配的文件。
唯一的问题是,如果目录包含许多文件,那么你在内存中占有一个大数组。
答案 2 :(得分:-2)
system "find / -name #{my_pattern}"