Se souvenir du résultat (habituellement de calculs) d'un appel de méthode afin que vous ne avez pas besoin de recalculer la prochaine fois que la méthode est appelée est connue comme memoization donc vous voudrez probablement en savoir plus à ce sujet.
Une façon de réaliser que Ruby est d'utiliser une petite classe wrapper qui stocke le résultat dans une variable d'instance. par exemple.
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
Et vous pouvez faire:
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"]
Note: l'opérateur effectue une mission ||=
que si la variable du côté gauche fait la valeur false. c'est-à-dire @matches ||= find_matches
est un raccourci pour @matches = @matches || find_matches
où find_matches
ne sera appelée que la première fois en raison d'une évaluation de court-circuit. Il y a beaucoup de other questions qui l'expliquent sur Stackoverflow.
légère variation: Vous pouvez changer votre méthode pour retourner une liste de tous les fichiers et utiliser des méthodes de Enumerable
telles que grep
et select
pour effectuer des recherches multiples sur la même liste de fichiers. Bien sûr, cela a l'inconvénient de garder toute la liste des fichiers en mémoire. Voici cependant un exemple:
def find_all
fs = []
Find.find("./") do |f|
fs << f
end
fs
end
Et utilisez-le comme:
files = find_all
files.grep /\.xml/
files.select { |f| f.include? '.cpp' }
# etc
Pouvez-vous clarifier un peu la question? Que voulez-vous dire par * exécuter Find.find ("./") seulement une fois *? – mikej
Je pense que le demandeur veut mettre en cache le résultat de 'Find.find ('./')'. – Swanand
@Swanand ah, merci! Je vais essayer de répondre à cette question. – mikej