Запоминание (обычно вычислительно интенсивный) результат вызова метода, так что вам не нужно пересчитывать его в следующий раз, когда вызывается метод известен как 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"]
Примечание: оператор ||=
выполняет задание, только если переменная на левой стороне делает принимает значение ложь. то есть @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
Не могли бы вы немного разъяснить вопрос. Что вы подразумеваете под * выполнением Find.find ("./") только один раз *? – mikej
Я думаю, что искатель означает кешировать результат 'Find.find ('./')'. – Swanand
@Swanand ах, спасибо! На этой основе я получаю ответ. – mikej