Запоминание (обычно интенсивного в вычислительном отношении) результата вызова метода, так что вам не нужно пересчитывать его при следующем вызове метода, называется памятка , так что вы будете вероятно, хотите узнать больше об этом.
Один из способов добиться этого в 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
будет вызываться только в первый раз из-за оценки короткого замыкания. Существует множество других вопросов , объясняющих это в 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