16 Apr 2004 14:10
Re: New map helper method
On 16 Apr 2004, at 00:31, Bruce Chapman wrote:
>> Yes, I see what you mean. I suppose the best thing would be
>> to supply the default value handling closure could be
>> supplied when the map is created. I can't think of a good way
>> of doing that, though.
>>
>>
>
> Agreed, this behaviour is really a property of the instance of Map as a
> whole, not of the particular method call.
It could be, though this sounds like one specific kind of Map
implementation - having the helper method means we can work with any
map implementation.
> What about
>
> classmap.setMissingValueGenerator({[]})
>
> ...
> classmap.get("classmethods").add(method)
>
> If setMissingValueGenerator() is never called, then get will return
> null as
> currently.
> Presumably in this case, classmap.containsKey() would need to be
> modified to
> always return true if setMissingValueGenerator() had been called.
> Because
> according to my reading of the spec for java.util.Map.get() and
> java.util.Map.containsKey() then setMissingValueGenerator() would imply
> there was a mapping for every possible key.
Agreed though this then becomes a different kind of map - where the
get() contract changes etc. Its now a 'growing on demand map'.
It may be better to implement this functionality as a specific Map
Facade/Proxy which delegates to an underlying real Map but overloads
the get() and containsKey() methods to allow this 'autovivication' to
take place.
i.e. we could implement what you describe in a specific Map facade,
which could proxy any Map implementation.
Then we could do things like
map = ['abc':123]
// wrap it in a facade that autovivicates
map = new AutoVivicateMap( map, { return [:] } )
// autovivicate
map.foo.bar = 123
The difference here is we have to explicitly wrap a map to enable this
feature - rather like when we make a Map immutable or synchronized.
We could consider adding a helper method to wrap this up, so any Map
can be easily converted into an autovivication map.
Already we can do
map = map.immutable()
so how about
// lets make an auto-vivicating map which auto-creates nested maps
map = ['abc':123, 'x':'zzz'].autovivicate { return [:] }
map.x.y.z.whatever = 456
James
-------
http://radio.weblogs.com/0112098/
RSS Feed