From: Trans Date: 2008-09-05T22:02:54+09:00 Subject: Re: Extend OpenStruct's functionality with explicit default value On Sep 5, 7:54 am, "Robert Klemme" wrote: > Hi, > > I just had a use case where I wanted to have several counters and not > store them in a Hash because of the nicer syntax of OpenStruct. > Currently, the code has to do > > counters = OpenStruct.new > ... > counters.foo ||= 0 > counters.foo += 1 > > For obvious reasons I'd like to get rid of the initialization. > > The suggestion would be to do this: if the argument to > OpenStruct#initialize is not a Hash use it as default value which is > returned for undefined properties. As far as I can see this won't > break existing code since the default is nil.  With the change one > could do > > counters = OpenStruct.new 0 > ... > counters.foo += 1 > > We could go even further and copy the Hash approach by also allowing a > block which is invoked when a property is accessed for the first time. >  Block argument would be the symbol of the property and the return > value would be used to initialize the property.  Then you could do > > data = OpenStruct.new {[]} > ... > data.animals << "cat" << "dog" > > or even > > data = OpenStruct.new do |sym| >   case sym >   when :animals : [] >   when :dictionary : {} >   end > end > > In other words: declarative lazy initialization. > > Again, existing code would not be affected. > > What do others think? I recently submitted a patch that allowed OpenStruct to take a self yielding block, e.g you could do: data = OpenStruct.new do |o| o.animals = [] o.dictionary = {} end I don't really see that much use for complex lazy initialization as you suggest. Though, I can see the Hash block form being useful. Maybe that would be a better use of the block. Actually, both could be supported if we differentiate on the arity of the block. With two args: OpenStruct.new{ |o, k| o[k] = [] } Note, my patch also add #[] and #[]=, which are more important changes. Robert would you like to update my patch to support the Hash block notation and resubmit it? T.