Hey,
I’m currently trying to create some kind of hierarchial data class. Kind
of like “sparse” data layers that sit on top of each other and let
lookups “fall through” them.
An example of this would be for multiple configuration layers
(application defaults, user defaults, current settings) - the idea being
that any change in the app defaults (including live changes) propagates
through to any derived settings where that value has not been overridden
from the default.
I have hacked something out which comes maybe 20% of the way, and was
hoping for suggestions to make this nicer. Here’s what I have so far:
···
===
class DataDelegator
def initialize(parent=nil, hash=nil)
@parent = parent
@hash = hash
@hash = Hash.new if @hash == nil
end
def
if @hash.has_key?(key)
return @hash[key]
elsif @parent != nil
return @parent[key]
else
# raise "no such member"
return nil
end
end
def []=(key,value)
@hash[key] = value
end
end
app_defaults = DataDelegator.new
app_defaults[“foo”] = "default_foo"
app_defaults[“bar”] = "default_bar"
app_defaults[“baz”] = “default_baz”
user_defaults = DataDelegator.new(app_defaults)
user_defaults[“foo”] = “user_foo”
current_settings = DataDelegator.new(user_defaults)
current_settings[“baz”] = “my_baz”
puts current_settings[“foo”]
puts current_settings[“bar”]
puts current_settings[“baz”]
===
This outputs:
$ ./test.rb
user_foo
default_bar
my_baz
So it kind of works, but I’d really like it not to use a hash, ideally
I’d like to access current_settings.foo, and not be allowed to lookup
something not found in the instance or any of its parents (very much
like a class hierarchy). I’d like current_settings.each to do the right
thing, and even nicer would be the ability to do stuff
like:
current_settings[“list of stuff”] << "whoopie"
and have that .dup the parent’s list before appending to it, and have
current_settings[“some array”].clear not clear the array in some parent.
This is all so like a class hierarchy I wonder if I’m missing something
obvious that would stop this becoming rather hacky (I had considered
using method_missing to catch “foo=” and “foo” etc and do the lookup
from there).
Anyone got anything similar? Or maybe some suggestions?
Tom.
.^. .-------------------------------------------------------.
/V\ | Tom Gilbert, London, England | http://linuxbrit.co.uk |
/( )\ | Open Source/UNIX consultant | tom@linuxbrit.co.uk |
^^-^^ `-------------------------------------------------------’