AppleScript_ The Definitive Guide - Matt Neuburg [252]
This is indicative of another difficulty that besets the new scriptability programmer. There is no straightforward documentation stating directly what methods will be sought and called, and when, and in what order, and what the scriptability framework will do if it fails to find a method it's looking for (will it default to a different method, or will it throw an error declaring your class not KVC-compliant, or will it return a mysterious error to the script, or what?). So you can never be quite sure what you need to implement and what method the framework may decide to call at any moment. Here you can see me working around this difficulty by implementing the same functionality twice. And I do the same thing in the last part of the MyObject category:
-(void)removeObjectFromPersonsArrayAtIndex:(unsigned int)index {
[self returnError:OSAMessageNotUnderstood string:nil];
}
-(void)removeFromPersonsArrayAtIndex:(unsigned int)index {
[self returnError:OSAMessageNotUnderstood string:nil];
}
@end
That code is to prevent the user from deleting a person. I've implemented two methods that do the same thing because the framework seems to complain on different occasions if I fail to implement either one, and I don't know why; lacking clear documentation, it seems easiest to fall back on a double implementation and move on.
With all of that in place, the previous test script still works perfectly. In addition, our application can now successfully return an object reference; and it now responds coherently to the user's attempts to do things we don't permit:
tell application "Pairs"
get name of every person -- {"Jack", "Jill"}
delete person "Jack"
-- error: Pairs got an error: person "Jack" doesn't understand the delete message
make new person
-- error: Pairs got an error: Can't give person empty name
make new person at end with properties {name:"Moe"}
-- person "Moe" of application "Pairs"
set name of person "Jill" to "Mannie"
set name of person 1 to "Mannie"
-- error: Pairs got an error: Can't give person same name as existing person
make new person with properties {name:"Mannie"}
-- error: Pairs got an error: Can't give person same name as existing person
end tell
Now let's add some more features. Let's give a person an additional property: gender, which is either male or female. This is simply to illustrate how you implement an enumeration. The Person class will need an instance variable, gender, whose value is an int, and we should probably add accessors gender and setGender. To define the enumeration and its enumerators for AppleScript, you want something in the dictionary like this:
Back in our Objective-C code, we define the same enumeration, like this:
enum {
MALE='gMAL',
FEMALE='gFEM'
} genders;
The match between the four-letter codes in the dictionary and our Objective-C code is crucial. Now, in the dictionary, we add the property to the person class:
(Observe that I do not make the common mistake of giving the property the same four-letter code as the class.) The Cocoa key "personGender" means that in our Person class the accessors personGender and setPersonGender: will be called. Implementation of these in the category on Person is straightforward; in my implementation I've allowed (and indeed required) the user to supply a gender when creating a person, but I've made it illegal for