On Sat, 22 Jan 2005 06:53:45 +0900, Anders Engströí <aengstrom / gnejs.net> wrote: > Another option is to use the :new method on the class to implement the > class Section > > class << self > # Called to get (or create) new instance > def new(id) > cached_instances()[id] || cached_instances()[id] = super > end > > def cached_instances() > @cache = {} unless @cache > @cache > end > end > > # Called on new instance > def initialize(id) > puts "Creating a new instance" > @id = id > end > > end Equivalent, but somewhat more concise and rubyish (IMO): class Section class << self # Called to get (or create) new instance def new(id) cached_instances[id] ||= super end def cached_instances @cache ||= {} end end # Called on new instance def initialize(id) puts "Creating a new instance" @id = id end end Changes: 1) The ||= operation is very useful for defaults. The statement a ||= b simply expands to a = a || b which is equivalent to the a || a = b that you had written. It is also equivalent to the a = b unless a which you had in the second function. 2) An empty parameter list is usually unnecessary, thus you can both define and call cached_instances without needing the '()'. Attaching an empty parameter list differs from no parameter list in only two cases I can think of; a) super vs. super() and b) disambiguating between a local variable and method of the same name (this may not even be an issue). 3) The return value of a ||= b is the new value of a (either what it was, or b if it didn't have a previous value), so the explicit mention of @cached as the return value is unnecessary in cached_instances. Jacob Fugal