Joy Online Manual
NAME |
objc:teach - Add new methods to objects |
SYNOPSIS |
objc:teach objectList ?-protocols protocols? skills
DESCRIPTION |
To let you make full use of the flexibility of an interpreted language, Joy introduces a new concept into object-oriented programming, called skill. Skills are exactly like methods, but there is one difference: Methods are always the same for a whole class of objects, but skills can be taught to single objects at run-time.
Without skills, if you needed to customize the functionality of an object you had to implement a new subclass which contained the necessary methods. But this only makes sense if you need many objects with the new functionality. In the much more common situation where you need just one object to respond to one message differently than other objects of its class, you had to resort to tricks like the target-action paradigm, or the delegate mechanism. But all of these are rather limited in the customization hooks they offer: You have only one target and one or two actions, only one delegate, and the delegate is messaged only at certain times. These limitations came directly from the nature of Objective-C as a compiled language. Only classes could have methods and instance variables because only classes were known to exist at compile time. Now, with Joy at your disposal there is no need to stick to the old limitations: You can associate both Joy code (skills) and data (property instance variables) with individual instances. The skills you define are registered with the Objective-C run-time environment like any Objective-C method, and can be called from Objective-C transparently! Again, Joy takes care of the conversion from binary to Joy strings and back. If you call a Joy skill from Joy, the skill is called directly, like any Joy procedure; arguments and return types will be checked for correct syntax, however, if the Joy variable objc:tclTclTypeCheckingEnabled is set to a nonzero integer value (the default) in the first interpreter that loaded Joy (performance of debugged programs will be somewhat better when type checking is disabled). If you have more than one Joy interpreter in your application, the Joy skill will always execute in the context of the interpreter that defined it (it will have access to the correct global variables, etc). When an interpreter is deleted, all Joy skills defined by it are deleted also. Joy skills are inherited and overridden exactly like methods, the only difference is that the inheritance hierarchy can have an additional bottom layer at the instance level. Both class and instance skills can be defined; it is illegal to define class skills for instance objects. You can override an Objective-C implementation of a method with a Joy skill, or one Joy implementation with another (even in a different interpreter). The old implementation is not lost and can still be called Every Joy skill has two additional hidden parameters, self and _cmd, containing the instance receiving the message and the selector, like in Objective-C. Inside a skill body there exist three special targets for messages: super, former, and objc. The super target works exactly like the Objective-C construct of the same name; note that when you message super from a skill defined for an instance, the message dispatcher will start looking for an implementation at the level of the instance's class, not its superclass. If you message the former target, the message dispatcher will use the implementation of the selector that it would have used just before the currently executing implementation was added (that includes superclass implementations); the objc target works in the same way, but looks only for an Objective-C implementation (disregarding all Joy skills); if no super, former or objc implementation is found, the call will just return $self. There is an additional command that is only usable inside a skill body: You can use iset instead of the set command to set or read the instance variables of the messaged object. If you iset a variable that is not an Objective-C instance variable, Joy will interpret that as a request to set or read a property instance variable. Property instance variables live in a Tcl array at global level that is named $self, so you have one independent variable name space per object instance (and interpreter). This array is unset completely (in all interpreters) when the object is deallocated. You can use the objc:deallocTrace command to execute Joy code whenever this happens. The first parameter to the objc:teach command is a list of classes and objects that you want to teach the skills. If -protocols is given, Joy will then check for each element of objectList and protocols if the object or class implements all skills required by the protocols, and, if yes, make it adopt the protocols. The skills parameter is a list of skills in a syntax much like in Objective-C: Each skill starts with a plus- or minus-sign (for class skills and instance skills, respectively) followed by a blank and the skill's return type (default id). Then the name of the skill, the parameters and the implementation follows. The parameters may be written between the colons of the skill name just like in Objective-C. Each parameter is a list with two elements, the first element is the type of the parameter in Joy syntax, the second being the name, or you specify a single string with the parameter's name (which has default type id). Variable argument lists are supported if the variable arguments are all of the same type as the last fixed argument (or {char *} if there aren't any fixed arguments), and their promoted size equals that of a {void *}; you declare a method with variable arguments by naming its last argument args. When a variable argument skill is called from Objective-C, Joy will stop converting and pushing arguments into the args Tcl list only after it has seen a null pointer value. |
EXAMPLE |
tcl> objc:teach NSObject { # teaching a skill to a class
- void test {
puts "instance test"
}
# you can have comments between skill implementations
+ void test {
puts "class $self test"
}
}
tcl> set o1 [[NSObject alloc] init]
NSObject@0xce398
tcl> set o2 [[NSObject alloc] init]
NSObject@0x16060c
tcl> objc:teach "$o1 $o2" { # teaching a skill to 2 instances
- void test {
# this will call NSObject's version
super test
puts "special test"
}
}
tcl> $o1 test
instance test
special test
tcl> $o2 test
instance test
special test
tcl> NSButton test
class NSButton test
SEE ALSO |
objc:deallocTrace
objc:info
objc:newClass
objc:typedef
objc:unteach
KEYWORDS |
class, inheritance, method, skill |
Index |