4

One of my ruby classes draws data from a rather large, local, XML file that will only change with a new deploy.

Is the best practice in this case to keep the document as a constant, like:

class Product 
  XML_DOC = Nokogiri::XML(open("#{Rails.root}/myxmlfile.xml"))
end

or to access the document through a class method, like:

class Product 
 self.xml_doc
    Nokogiri::XML(open("#{Rails.root}/myxmlfile.xml"))
  end
end

I think that the class method may be the way to go, since it will be easier to mock in tests, but what's considered the best-practice for keeping an in-memory file like this?

SooDesuNe
  • 9,880
  • 10
  • 57
  • 91
  • 1
    I like gioele's answer to your specific question, but I don't like your question. :-) Rather instantiate a product object as part of program setup. "I only need one" is not a good reason to throw object orientation out the window. – sheldonh Nov 06 '11 at 15:31

1 Answers1

5

This is the most common idiom:

class Product 
    def xml_doc
       @@xml_doc ||= Nokogiri::XML(open("#{Rails.root}/myxmlfile.xml"))
       return @@xml_doc
    end
end

The ||= operator says "if the variable is nil, calculate the result of the expresion and store it, otherwise do nothing". This idiom is called "memoization".

Do no think of constants as a way to optimize your code, in Ruby they are not really constant anyway.

gioele
  • 9,748
  • 5
  • 55
  • 80