R
Robert Klemme
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?
Kind regards
robert
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?
Kind regards
robert