On 09/10/2010 04:22 PM, Adrian Crum wrote:
--- On Fri, 9/10/10, Adam Heath<[email protected]>  wrote:
On 09/10/2010 01:03 PM, Adrian Crum
wrote:
--- On Fri, 9/10/10, Adam Heath<[email protected]>
wrote:
I haven't had this be a problem for
me in production anywhere, but I noticed that
when
remove(Object) is called, it'll remove the value
from the
top-most map in the stack.  This then means
any queries
for the key will fall-thru to lower maps, which
is
definately *not* what should occur.

That would depend on your point of view. From a
variable scoping viewpoint, that would be the correct
behavior.

Let's say I have two variables, both with the same
name. One is declared early on and could be considered
"global." The other is declared inside a method and is
considered "local." If I remove the local variable, I would
expect the global variable to still be there.

java.util.Map.remove(Object) says that it removes the
object from the
map, such that Map.containsKey(Object) will return false
afterwards.
That is what the contract states, and that's what
MapStack/MapContext
should follow.

If you want another method to do what you say, then I can
go ahead and
implement that.

As it is, if an instance of MapStack/MapContext is passed
to legacy
code that only deals with maps, then it'll break.

Like I said, it's a matter of perspective. What is MapStack's purpose - to 
implement a Map, or to implement variable scoping? Based on the MapStack code 
and how it is used in the framework, I think it is the latter.

It would be helpful to hear from others.

MapStack implements Map. It must follow the Map contract. If you remove the Map from the implements, then it can do whatever we want.

I can correct these problems, it's busy work for me.

Additionally, entrySet() returns an unmodifiable
Collection
of Map.Entry.  However, those entries point
to the
*original* map.  If someone called setValue()
on the
entry, it would modify the original map, instead
of
inserting a value into the top-most map.

Huh? How can you modify an unmodifiable collection? If
that's possible, then my recommendation would be to enforce
the unmodifiable part and not worry about which scope is
being changed.

You're not modifying the collection.  You're modifying
a value *in*
the collection.  Collections.unmodifiableFoo only
protects the collection.

Collection.iterator().next().setValue("foo") should place
an override
entry into the top-level map, and then change the entry
instance
that's in the underlying protected read-only collection.

If it's truly unmodifiable, Collection.iterator().next().setValue("foo") should 
throw an exception. In other words, the MapStack should be wrapped with an unmodifiable 
Map, and then return an entry set from the unmodifiable Map, or implement unmodifiable 
Map.Entry.

Again, that's not what the Map contract says.

MapStack implements Map, so that means programmers who see it expect it to follow the rest of the java.util.Map universe. Plus, MapStack gets passed around to methods that only take a Map, and those methods(and anything else they may call) expect it to behave correctly.

Reply via email to