避免在Ruby中多次调用Find.Find(“/”)

避免在Ruby中多次调用Find.Find(“/”),ruby,block,Ruby,Block,我不确定这方面的最佳策略是什么。我有一个类,可以在文件系统中搜索特定模式的文件。我只想执行一次Find.Find(“./”)。我将如何处理这个问题: def files_pattern(pattern) Find.find("./") do |f| if f.include? pattern @fs << f end end end def文件\u模式(模式) 查找。查找(“./”)do|f| 如果包括?图案

我不确定这方面的最佳策略是什么。我有一个类,可以在文件系统中搜索特定模式的文件。我只想执行一次Find.Find(“./”)。我将如何处理这个问题:

  def files_pattern(pattern)
    Find.find("./") do |f| 
      if f.include? pattern
           @fs << f
      end
    end
  end
def文件\u模式(模式)
查找。查找(“./”)do|f|
如果包括?图案
@fs关于
系统“find/-name#{my_pattern}”

如何记住方法调用的结果(通常是计算密集型的),这样下次调用该方法时就不需要重新计算它了,这被称为,因此您可能想了解更多有关这方面的信息

实现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
然后像这样使用它:

files = find_all
files.grep /\.xml/
files.select { |f| f.include? '.cpp' }
# etc

如果我正确理解您的问题,您希望运行Find.Find将结果分配给实例变量。您可以将现在的块移动到一个单独的方法,并调用该方法以仅返回与您的模式匹配的文件


唯一的问题是,如果目录包含许多文件,那么内存中就有一个大数组。

如果希望得到结果,请使用回勾号,而不是直接将结果发送到stdout。在Windows和任何其他可能没有可用的find或使用相同参数的平台上,这肯定会失败。我会这样做只是作为最后一项措施。实际上,我在发布后立即删除了这个答案(但显然它没有被删除),因为它的问题比我第二次阅读这个问题后提到的要多。你能澄清一下这个问题吗。你说只执行一次Find.Find(“./”)是什么意思?我想询问者的意思是缓存
Find.Find(“./”)
@swand的结果,谢谢!我将在此基础上尝试一个答案。这没关系,但是如果我现在想先查找.xml,然后查找.cpp、.c、.h,并且我在文件系统的很大一部分上都这样做,那么我会多次调用find.find(“./”)。或者,嗯。。我想我需要将FileSystem的所有条目存储在一个textfile中,并将Finder类应用于textfile,这应该比find()更快。当然,每次在进行筛选之前,我都必须更新textfile。@poseid我在答案的末尾添加了一个变体。看看这是否有用。谢谢。我基本上错过了将块转换回方法的要点。
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