Ruby on Rails: an efficient use of a class in lib/ directory
I've been building a text parser. Ideally, it should be a static class:
keywords = Dictionary.parse(text)
However, the parser (lib/dictionary.rb) has to load some data (for instance, 'stop_words.txt') in开发者_如何学Pythonto memory as an array.
Therefore, as I understand, it can't be a static class, since I need a constructor, which would load that data before the parser can be used.
Then:
lib/dictionary.rb
def initialize
@stop_words = load_stop_words
end
models/entry.rb
def parse
@dictionary = Dictionary.new
self.keywords = @dictionary.parse(self.text)
end
But how inefficient is that? Does it mean, that if I have 1000 entries, the Dictionary class loads 'stop_words.txt' 1000 times, even if the contents of the file are almost constant?
I guess, I am missing something here. There must be a better solution - either without creating multiple instances of the Dictionary class, or by loading data only once, when the application is running.
So your pattern is that you would like a single instance of the object ( which is effectively constant and read-only after instantiation ) which is accessible from many callers but instantiates itself the first time it is called?
The name of this pattern is the Singleton and Ruby has it available as a mixin.
I would use an initializer, which is stored in config/initializers
and those are only loaded on startup, and perfect to load configuration files or setting up stuff. So your Dictionary
is under '/liband in '/config/initializers
you create a file called dictionary.rb
(or similar, the name is actually not important)
which contains the code to load your keywords.
If you are in Rails (as I assume by the tag and the lib directory) then it doesn't get loaded N times: lib files gets loaded only at Rails booting (if you change them, you need to restart the application) and so stop_words
will be loaded just one time. Little example (lib/timenow.rb
):
module Timenow
@now = Time.now
def self.doit
Rails.logger.warn "TIME NOW IS: #{@now}"
end
end
In any controller, Timenow.doit
logs the time this module was loaded.
精彩评论