Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!)
Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!)
- Subject: Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!)
- From: Nat! <email@hidden>
- Date: Sun, 6 Jun 2004 21:32:08 +0200
Am 06.06.2004 um 14:13 schrieb Marcel Weiher:
On 5 Jun 2004, at 17:49, Nat! wrote:
Am 05.06.2004 um 16:00 schrieb Marcel Weiher:
First, there is *nothing* whatsoever in the behavior of a
dictionary, in general CompSci terms, that says its keys should be
copied. A dictionary is simply a mapping of keys to values. I have
never seen either a definition of dictionary or an implementation
that does the copying (apart from this one).
The practical reason for copying
You are replying to the theoretical reasoning with a practical
argument, but have snipped the practical reasoning. Anyway...
On the basis of theory, I could also say that there is nothing that
forbids it being copied. No ?
is, that in 95% of all cases the keys of dictionaries are strings.
And roughly 100% of those will be strings that do not change
afterwards, wether they are constant strings or not. If you design
your class in such a way that it assumes (and almost requires) string
keys, then it should be called a NSStringDictionary. And 95% of all
statistics are made up out of thin air on the spot ;-)
Well the rest 4% are going to be NSDatas and NSNumbers probably :)
Having mutable objects as keys is of course a pandaras box of errors,
This is a theoretical fear. It isn't an practical problem.
Yeah sure. As long as you can pass in mutable strings as keys, and have
them be changed outside of the NSDictionary it is a practical problem.
I mean if that isn't a practical problem. I don't know what is.
I can't believe that you are unaware that this:
- (void) takeAString:(NSString *) s
{
[lut_ setObject:[NSCalendar date]
forKey:s];
}
will create a hard to trace bug, if someone happens to pass in s as a
mutable string and changes the contents after calling takeAString:. How
could you harden this code ? The only way is this, bloating the user
code (many places instead of one place (NSDictionary)):
- (void) takeAString:(NSString *) s
{
[lut_ setObject:[NSCalendar date]
forKey:[[s copy] autorelease]];
}
I think reading stringValue from a AppKit field editor gives you a
mutable string for example. I remember running into that problem early
on :)
therefore the key gets copied.
You conveniently snipped my analysis of this part, so here it goes
again:
- copying the key is unnecessary, because you can easily specify that
requirement in the contract
How would you do that in Foundation ? Only by documentation, not very
safe...
Also this would "bloat" client code.
- copying the key is unnecessary, because (string) keys typically
won't change, even if they theoretically could
Exactly. Typically(!) they wont change. But I already wrote something
about that...
- copying the key does not solve the problem, because copied items
can still change under you
But it solves the problem for the highest frequency key classes,
NSData, NSNumber and NSString.
As we know, copy on immutable objects is usually just a retain.
Relying on a property of objects
What's the problem with that ?
This retain would have to be done anyway, if you are not copying.
So it is not a design bug but a design choice and a good one.
In a word: no.
It is not a good design choice because it
(a) attempts to solve a problem that DOES NOT EXIST, practically
(and in fact pretty much relies on it not existing in the first
place!)
Does exist. You even say it doesn't appear "typically".
(b) then goes on to not actually solving the blasted problem
Does solve it for the vast majority of uses and usually at no extra
cost!
(c) prevents uses of the class that are perfectly legitimate for a
dictionary
Yup, if it can't be copied it isn't served by NSDictionary. No problem,
as NSMapTable is there.
(d) where other solutions exist that work at least as well if not
better without introducing these problems
???
Second, the definition is a mapping of (object) keys to values. NOT
of the key's value to a value. Since one of the fundamental
properties of objects is that they have identity (See RM-ODP and
other definitions of the term), the fact that a *different* object
is actually used as a key is, at the very least, an odd choice.
By that reasoning you would create two entries for
[dictionary setObject:@"foo"
forKey:[@"bar" mutableCopy]]; // yeah, leak, so what
[dictionary setObject:@"xxx"
forKey:[@"bar" mutableCopy]];
No.
What do you mean no ? How would that not create two entries ?
With the current "design", you impose the constraint that copies must
have the same hash and compare equally. Which may not be
desirable/feasible. And it is also not documented, as far as I can
see.
What would that be good for, in the general case ? As the copy will
satisfy the -hash and -isEqual "identity",
Says who?? It certainly isn't listed as a requirement in the
NSCopying protocol. Neither is it listed as requirement in NSObject's
protocol documentation. In fact, NSObject's implementations -hash and
-isEqual: do not satisfy this "identity" you have conjured up out of
thin air.
Well thick air. What is the purpose of a copy, if it's isEqual method
doesn't find them to be equal. From the dox: "The exact meaning of
copy can vary from class to class, but a copy must be a functionally
independent object with values identical to the original at the time
the copy was made."
If the values are identical, isEqual: failing would be a strange thing
indeed. Otherwise we would be back at pointer equality checking (-> two
entry problem).
On the other hand the following appears in -hash:
If a mutable object is added to a collection that uses hash values to
determine the objects position in the collection, the value returned
by the hash method of the object must not change while the object is
in the collection. Therefore, either the hash method must not rely on
any of the objects internal state information or you must make sure
the objects internal state information does not change while the
object is in the collection. (Note that it can be difficult to know
whether or not a given object is in a collection.)
This actually blatantly contradicts the implementation in NSDictionary!
Well actually both together just state, that if your class is mutable
and doesn't convert to immutable when being copied, that you should be
extra careful to use it as a key. As this will produce hard to find
bugs "(Note that it can be difficult to know whether or not a given
object is in a collection.)", someone must have gone down that road
before :)
NSMapTable doesn't bite you. Use it. It is also a dictionary in CompSci
terms.
Ciao
Nat!
------------------------------------------------------
A good dog, though a fool.
Who wants a smart dog! -- R.A. Lafferty
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
References: | |
| >Ugly bug in Foundation, beware! (From: Ondra Cada <email@hidden>) |
| >Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Alastair Houghton <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Ondra Cada <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Alastair Houghton <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Brent Gulanowski <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Alastair Houghton <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Ondra Cada <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Marcel Weiher <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Brent Gulanowski <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: "Louis C. Sacha" <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Marcel Weiher <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Nat! <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Marcel Weiher <email@hidden>) |