OCUDL: Objective-C User Defined Literals
Recently a GitHub project has been published that aims to introduce custom literals to Objective-C. The syntax is simple: $(#FF0000)
would return [UIColor redColor]
while $(null)
could return NSNull
. It also allows classes to register their own mapping. Full details can be found on Dustin Bachrach's post about the OCUDL.
Alternative Syntax Suggestion
While OCUDL syntax is simple, it has a few issues. Firstly, there is no way for the compiler to know the returned object's type. While there is a trend towards using instancetype
rather than id
for return types, this is a step backwards for type checking. It is made worse as the implementation relies on prefixes and suffixes, something that may clash. I would propose an alternative syntax:
$(NSURL)[@"http://apple.com"];
$(NSURLRequest)[@"http://apple.com"];
$(UIColor)[0xff0000];
$(NSSet)[@[@1, @2, @3]];
This can be implemented with the following macro:
#define $(cls) (cls *)((id)[cls class])
To make a class support the syntax, there is no need to register anything with a manager class, the only thing that needs to be implemented is one or both of the following methods:
+ (id)objectAtIndexedSubscript:(NSUInteger)idx;
+ (id)objectForKeyedSubscript:(id)key;
The NSSet
example can easily be implemented in the following way:
@implimentation NSSet (AOCUDL)
+ (id)objectForKeyedSubscript:(id)key
{
return [self setWithArray:key];
}
@end
This uses the same syntax used for the new object subscripting syntax (e.g NSArray
or NSDictionary
). This also allows the returned object to be cast to the correct class, allowing for warnings and errors to be correctly generated. It also allows for two classes to respond to the same object in different ways (e.g. NSURL
and NSURLRequest
above).