discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Key-Value Operators on Array


From: Doc O'Leary
Subject: Re: Key-Value Operators on Array
Date: Thu, 06 May 2004 16:09:26 -0500
User-agent: MT-NewsWatcher/3.4 (PPC Mac OS X)

In article <mailman.3738.1083863450.1061.discuss-gnustep@gnu.org>,
 Philip Motteli <Philip.Moetteli@tele2.ch> wrote:

> My question, proposal is: Why not use this '@' as a general mark, that 
> an operator should be sent to the array itself? Not restrict its use to 
> these few mentionned predefined operators?
> This wouldn't be a problem for code written for Cocoa. Cocoa would just 
> not have that feature and (probably) raise an exception.

Actually, support in Cocoa *is* for a general @ prefix.  I still think 
the whole idea is a bad one, though.  Here is a letter I wrote to 
cocoa-feedback last October when they changed the behavior:

> It now returns an array that contains the results of sending  
> -valueForKey: to each element in the array, with NSNulls corresponding  
> to each element returning nil from -valueForKey:. It is now possible  
> however to access inherent properties of arrays by prefixing the key  
> with a '@'.

This is a bad choice.  I'm discovering that it has not only broken a  
lot of my code, but it is counterintuitive to how items would be  
normally used via key-value coding.  It also doesn't address how NSSet  
behaves (annoyingly differently, I assume).  Allow me to propose some  
approaches that would be more useful to developers.

Generally, a collection should not assume a pass-through.  That is,  
when I key-value an object, I want values for that object and not for  
some contained object(s).  The whole @ notion must be scrapped because  
it involves a break from that, making what is otherwise a common case  
now exceptional.

To support the concept of a pass-through, add key-value support to  
NSEnumerator and have *it* be the means of collecting results (key  
collision with -nextObject is terribly unlikely!).  For example:

NSArray  *vooDone = [someArray valueForKeyPath:  
@"objectEnumerator.youDoThatVoodoo"];

Further, for an array, there is no way to key-value for a particular  
object (except lastObject), which is a very common need.  As a simple  
solution, NSArray should resolve numerical keys as an index.  For  
example:

id ultimateLocation = [someArray valueForKeyPath: @"42.location"];

I've already hacked that support previously for my software (see  
http://www.subsume.com/static/WebObjects/SubsumeSite/SubsumeSite/Tech/ 
Software/STXML/Use.html), but it would be really nice if index  
resolution were done by default.

As for NSDictionary, the problem is a bit more tricky because of the  
(static) keys it has for itself as well as the (dynamic) keys it has  
for objects it contains.  But it also has its own methods for access to  
contained objects by key.  I would thus suggest that using the  
-object... methods does resolution starting with (and perhaps only  
with) the dynamic, contained objects while the -value... methods start  
resolution with the dictionary itself.

Alternatively (or perhaps additionally), it is possible to *reasonably*  
overload the key path methods to reflect an explicit resolution policy.  
  For example:

NSString *dictionaryDescription = [someDictionary valueForKeyPath:  
@".description"];
NSString *containedDescription = [someDictionary valueForKeyPath:  
@"description"];

That is, an initial period as a key prefix is used to indicate that  
resolution begins with the dictionary object itself.  This could even  
be used in more complex paths, where two periods would then indicate  
first the key delimiter and second the "local" resolution:

NSString *infoDescription = [localException valueForKeyPath:  
@"userInfo..description"];

This all gets rid of the @ nonsense and breaks nothing.  Please  
consider this solution for the next framework update.  I would be happy  
to discuss any problems with or additions that could be made to it.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]