Re: Adding To A List
Re: Adding To A List
- Subject: Re: Adding To A List
- From: has <email@hidden>
- Date: Fri, 3 Jun 2005 16:55:24 +0100
kai wrote:
>>Some situations _require_ shallow copying, some _require_ deep copying. Others it doesn't matter which you use
>
>That's even more interesting, has. I wonder if you could perhaps offer an insight into the criteria for deciding the most appropriate method for a given situation? I'm sure it would be appreciated. :-)
You use a deep copy when you want to fully duplicate an object and all the objects within it. For example, you might represent a mathematical matrix as a list of lists; if you want a copy of that matrix you'd make a deep copy because you don't want subsequent changes to one of these matrices also popping up in the other.
You use a shallow copy when you want to duplicate an object without duplicating any of the objects within it. For example, your program might store unique personnel information as a list of records; if you duplicate that list then you'd use a shallow copy as you don't want two copies of each person's information floating around your application, getting out of sync because subsequent changes made to one copy of a person's record aren't reflected in the other.
If your list contains script objects then you almost always want to use a shallow copy, not a deep copy, as duplicating a script object with 'copy' duplicates not just the script object and all its contents but also all its parents and their contents as well. Very expensive, and may also break your program if those scripts refer to any shared global state, as each object will end up with a non-shared copy of that state.
There's an interesting example of shallow copying in AppleMods' Types library. Its Dictionary object uses a pair of internal lists to hold dictionary keys and their corresponding values. Users never interact with these private data structures directly; instead they use the object's methods - setItem(), getItem(), deleteItem(), etc. - to add, get and remove values.
Because users' code will sometimes need to get a list of all the keys in a dictionary, or grab a list of all its values which it can iterate over to manipulate each object in turn, dictionary objects also provide getAllKeys() and getAllValues() methods. However, these methods daren't return the original internal lists, because the user might add or change items in those lists and thereby break the dictionary object's internals. Nor does the getAllValues() method doesn't want to deep-copy the internal values list as the user will naturally want and expect to get the same objects back as they originally put in, not brand new copies each time. (Imagine the trouble this'd cause if a dictionary was being used to hold unique Document Controller objects in a document-based Studio app, for example.)
So getAllKeys() and getAllValues() make shallow copies of the internal lists and return those instead, ensuring the object's internal state can't be disrupted by anything the user might do to those lists, and without potentially introducing obscure bugs by handing them copies of their data to work on instead of the originals.
Now, had I used one of the sub-optimal approaches, chances are that 99% of that library's users would never find themselves in the exact circumstances that'd raise these bugs anyway. But a little bit of extra care and anticipation in planning and design ensures the other 1% won't have any reason to kill me either. :)
HTH
has
--
http://freespace.virgin.net/hamish.sanderson/
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Applescript-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden