En Objective-C, vous ne pouvez pas déclarer de noms de méthode où le dernier composant ne prend pas d'argument. Par exemple, ce qui suit est illégal.
-(void)take:(id)theMoney andRun;
-(void)take:(id)yourMedicine andDontComplain;
Pourquoi Objective-C a-t-il été conçu de cette façon? Était-ce juste un artefact de Smalltalk dont personne ne voyait le besoin de se débarrasser?
Cette limitation a du sens dans Smalltalk, car Smalltalk n'a pas de délimiteurs autour de l'appel de message, donc le composant final serait interprété comme un message unaire jusqu'au dernier argument. Par exemple, BillyAndBobby take:'$100' andRun
serait analysé comme BillyAndBobby take:('$100' andRun)
. Cela n'a pas d'importance en Objective-C où les crochets sont obligatoires.
La prise en charge des composants de sélecteur sans paramètre ne nous rapporterait pas beaucoup de toutes les manières habituelles de mesurer un langage, comme le nom de méthode choisi par un programmeur (par exemple, runWith:
plutôt quetake:andRun
) n'affecte pas la sémantique fonctionnelle d'un programme, ni l'expressivité du langage. En effet, un programme avec des composants sans paramètres équivaut à un programme sans. Je ne suis donc pas intéressé par les réponses indiquant qu'une telle fonctionnalité n'est pas nécessaire (à moins que ce ne soit les raisons invoquées par les concepteurs d'Objective-C; est-ce que quelqu'un connaît Brad Cox ou Tom Love? Sont-ils ici?) Ou qui disent comment écrire des noms de méthode pour que la fonctionnalité ne soit pas nécessaire. Le principal avantage est la lisibilité et l'écriture (ce qui est comme la lisibilité, seulement ... vous savez), car cela signifierait que vous pourriez écrire des noms de méthodes qui ressemblent encore plus à des phrases en langage naturel. Les goûts de -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
(que Matt Gallagher souligne sur "Cocoa With Love"-(BOOL)application:(NSApplication*)theApplication shouldTerminateAfterLastWindowClosed
, plaçant ainsi le paramètre immédiatement à côté du nom approprié.
Le runtime Objective-C d'Apple (par exemple) est parfaitement capable de gérer ce type de sélecteurs, alors pourquoi pas le compilateur? Pourquoi ne pas les soutenir également dans les noms de méthodes?
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface Potrzebie : NSObject
-(void)take:(id)thing;
@end
@implementation Potrzebie
+(void)initialize {
SEL take_andRun = NSSelectorFromString(@"take:andRun");
IMP take_ = class_getMethodImplementation(self, @selector(take:));
if (take_) {
if (NO == class_addMethod(self, take_andRun, take_, "@@:@")) {
NSLog(@"Couldn't add selector '%@' to class %s.",
NSStringFromSelector(take_andRun),
class_getName(self));
}
} else {
NSLog(@"Couldn't find method 'take:'.");
}
}
-(void)take:(id)thing {
NSLog(@"-take: (actually %@) %@",NSStringFromSelector(_cmd), thing);
}
@end
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Potrzebie *axolotl=[[Potrzebie alloc] init];
[axolotl take:@"paradichloroaminobenzaldehyde"];
[axolotl performSelector:NSSelectorFromString(@"take:andRun")
withObject:@"$100"];
[axolotl release];
[pool release];
return 0;
}