У Objective-C ви не можете оголосити імена методів, коли останній компонент не бере аргумент. Наприклад, наступне є незаконним.
-(void)take:(id)theMoney andRun;
-(void)take:(id)yourMedicine andDontComplain;
Чому Objective-C був розроблений саме таким чином? Це був лише артефакт Смолталка, від якого ніхто не бачив необхідності позбавлятися?
Це обмеження має сенс у Smalltalk, оскільки Smalltalk не має роздільників навколо виклику повідомлень, тому кінцевий компонент буде інтерпретований як одинарне повідомлення останнього аргументу. Наприклад, BillyAndBobby take:'$100' andRun
буде проаналізовано як BillyAndBobby take:('$100' andRun)
. Це не має значення в Objective-C, де потрібні квадратні дужки.
Підтримка безпараметричних компонентів-селекторів не допоможе нам у всіх звичних способах вимірювання мови, як називає метод, який вибирає програміст (наприклад, runWith:
а неtake:andRun
) не впливає на функціональну семантику програми, а також на виразність мови. Дійсно, програма з безпараметричними компонентами альфа-еквівалентна програмі без. Отже, я не зацікавлений у відповідях, які стверджують, що така функція не потрібна (якщо це не було зазначено причинами дизайнерів Objective-C; хтось випадково знає Бреда Кокса чи Тома Лава? Вони тут?) Або що кажуть як писати імена методів, щоб функція не потрібна. Основною перевагою є читабельність і зручність запису (що схоже на читабельність, лише ... ти знаєш), оскільки це означало б, що ти можеш писати назви методів, які ще більше нагадують речення на природній мові. Подобається -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
(на що вказує Метт Галлахер у "Какао з любов'ю"-(BOOL)application:(NSApplication*)theApplication shouldTerminateAfterLastWindowClosed
, таким чином розміщуючи параметр безпосередньо біля відповідного іменника.
Виконавча програма Apple Objective-C (наприклад) цілком здатна обробляти такі селектори, то чому б не компілятор? Чому б не підтримати їх також у назвах методів?
#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;
}