property :color, :type => Integer property :color, :type => String property :color, :type => Pathname * is a subclass of extlib's `Mash` (Hash with indifferent access). - in the * does not have to be performant. Obviously it can't suck, but we're not going to worry about say the overhead of converting values to `dsl_mash`es on assignment. ## Layering This is the key thing. We don't prescribe *any* resolution semantics except the following: * layers are evaluated in order to create a composite, `dup`ing as you go. * while building a composite, when a later layer and the current layer collide: - if layer has merge logic, hand it off. - simple + any: clobber - array + array: layer value appended to composite value - hash + hash: recurse - otherwise: error ### no complicated resolution rules allowed This is the key to the whole thing. * You can very easily * You can adorn an object with merge logic if it's more complicated than that ### duping (?) I'm not certain of the always-`dup` rule. We'll find out __________________________________________________________________________ ## Interface ### setter/getter/block * `obj.foo` -- returns value of foo * `obj.foo(val)` -- sets foo to val; val must not be `nil` * `obj.unset(:foo)` -- unsets foo want: * `obj.foo ||= val` -- sets foo to val if foo is unset, `false` or `nil` * `obj.default(:foo, val)` -- sets foo to val if foo is unset provisionally, these are `protected`: * `obj.get(:foo)` -- returns value of foo * `obj.set(:foo, val)` -- sets foo to val ### how hash-like is this? * obj.deep_get(:foo, :bar, :baz) # * obj.deep_set(:foo, :bar, :baz, val) # sets foo bar baz. - where property has a type, it uses that type - otherwise it uses Mash, and calls [] on it * TD votes NO on magic recursive hash behavior * `obj[:foo]` * `obj[:foo] = val` * `obj[:foo][:bar][:baz]` -- when this has a value * `obj[:foo][:bar][:baz]` -- when some or all of those have never been set? * `obj[:foo][:bar][:baz] = 1` -- when `obj[:foo]` has never been set * `obj[:foo][:bar][:baz] = 1` -- when `obj[:foo]` has never been set * `obj[:foo][:bar][:baz] ||= 1` -- **hard** ?I think? * `obj[:foo]` -- nil * `obj[:foo][:bar]` -- raise * `obj[:foo][:bar] = 3` -- - now obj[:foo][:bar] is 3 - and obj[:foo] is a ?dsl_object?? but `obj[:foo][:bar]` Suppose `obj[:foo]` is set to a Seems clear these should do the right thing: * `obj.merge` * `obj.reverse_merge` * `obj.keys` * `obj.values` * ... and a few more Also: * `obj.to_a`? * `obj.each`? * other crazy Enumerable properties? ### collection attributes | array | array | add or clobber | ### nested objects ### type co