While 2-letter prefixes were a good idea in the late eighties, nowadays there’s just not enough flexibility there.
There are those who suggest 4-letter suffixes for their library prefixes.
OpenGL uses 2-letter (‘gl’), 3-letter (‘glu’), and 4-letter prefixes (‘glut’) as enumerated in the BlueBook.
Apple’s ScreenSaver framework has an 11-letter prefix for all of its public symbols: “ScreenSaver”.
Some folks recommend deriving symbol prefixes from reverse domain naming conventions, to further reduce collision risk: “ComMacSteve”. Another advantage of using this technique is: no registration page required. There are downsides, of course.
Hmmm … I can’t quite come up with a clever conclusion to this note. Meditate on this for a while.
– MikeTrent
A solution is to use really long names, and then when you don’t want to use the really long prefix, to #define a shortcut… when your done with the shortcut, #undef it. This is similar to the concept of some other languages using the “namespace” and “using” kind of words.
Up until now, I’ve been ignoring prefixing and namespaces in Cocoa (except for Java packages, which I like). But now I’m in the process of writing an application that accesses class information defined by the user. This creates a possible collision. So my current solution (until if-when Apple adds namespace/package support to ObjectiveC) is to use the following code:
#define MyClass ComMyWebsitePackageName_MyClass … @interface MyClass …
My only immediate problem is that I have to go change it manually in Interface Builder, and this doesn’t solve anything if I accidentally include someone else’s (or even my own) header that already has a #define MyClass. But for now I think it’s better than nothing, and easier than writing out the full name all the time. This could also be used with prefixing, so that you would abbreviate your package name to a prefix. This would reduce #define collisions as well. – JediKnil
I like Knil’s scheme. One could also consider putting the #define’s in a prefix header that also imported the headers files. And there’s no need to do this in application code (only frameworks and bundles), so long as all code agrees that the no-prefix namespace is reserved to an application’s main bundle.
Anyone else have thoughts?
@compatibility_alias MyClass NetIconaraStupidLibraryMyClass;
Hey ho, MyClass and NetIconaraStupidLibraryMyClass are now two names for the same class. More ObjC than #defines, but can’t undef it though. –TheoHultberg
I moved Theo’s comment from the bottom of the page to here - because I believe it’s extremely relevant and deserves a bit more visibility. A link on RedHat’s site (below) claims that this keyword was “completely forgotten about”
http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/4/html/Using_the_GNU_Compiler_Collection/compatibility_alias.html http://developer.apple.com/library/mac/#documentation/DeveloperTools/gcc-4.0.1/gcc/compatibility_005falias.html (basically the same as above).
This is how to use the directive @compatibility_alias as an import directive, like in Java:
#import “NetIconaraStupidLibraryMyClass.h” // defines the class by the same name
@compatibility_alias MyClass NetIconaraStupidLibraryMyClass;
// now I can refer to MyClass instead of NetIconaraStupidLibraryMyClass, namespace problem sorted.
Although I dislike this idea on aestethical grounds, it works quite like proper namespaces. If you want to “import” a whole library, you can prepare a header file with all the @compatibility_alias directives, and import that header. –TheoHultberg
I believe this to be a problem that Apple should fix; we the developers are unfortunately going to run into collisions if left to our own devices. I personally have classes I wrote on my hard drive which include prefixes such as GL, LS, FD, FDGL, Meta, Emily, CBG, Ce, EK, Locate, and q. Now, only one of those (LS) is likely to ever get exposed API, which is why I didn’t put any of the rest in the list above, but you can see the problem quite clearly.
The problem is pretty simple:
Beyond being very silly, that is very, very unreadable. So,
Java’s com.domain.packaging.thingy seems to work pretty well. Anybody think it could be adapted (without the above ComMyDomainCollectionMap silliness) to ObjC?
– RobRix
I would like to see something like the following.
@namespace com.mycompany.mynamespace . . . @end
where the namespace hierarchy can be any reasonable number of levels deep.
Referencing fully qualified objects could be something like…
com.mycompany.mynamespace.MyObject *p = [com.mycompany.mynamespace.MyObject objectWithSomeParameter:foo];
Yuk, So something like the following becomes very popular…
@using com.mycompany.mynamespace;
** How would you propose dealing with code that uses objects from multiple name spaces? Namely using any Cocoa class with your name space.
And if those two namespaces both have classes named CoolWidget. (Extreme I know.) –TimothyHatcher **
which can specify a namespace name or a fully qualified type name. This could appear either at global (compilation unit), class, or method scope.
The runtime could default pre-namespace compiled code, or code not using the feature, to the global namespace as it essentially does now.
The remainder of the namespace rules (lookup and whatnot) could be stolen from Java or C++; as they both are fairly mature and work well. I would suggest C++ semantics as Objective-C++ already exists and it would cut down on surprises for C++ developers if they worked similarly…
PS you can do something like javas com.packaging.thingy already in cocoa:
Define a class which represents your package. *That class defines *class methods that return a class. *these classes can also represent packages in the same way. *import the top level class (package). *If you are adding a class to a package define a category.
then you do:
[Cocoa com] packaging] thingyClass]
to get your class. Not too hard methinks, doesn’t involve any language extensions. Don’t know why nobody does this already. :-) Perhaps even using CCD is unnecessary. – [[MikeAmy
Although this is a very creative solution, I believe it suffers from a serious flaw in usability: it looks like messaging, but has an entirely different meaning. It will be too distracting/confusing in actual usage. It needs to look different at a glance.
It also has s second serious flaw: it has no point. The point behind namespaces is to refer to a unique global name by an abbreviated local name. If you always have to refer to something by the full name, you might as well make the class names longer, e.g. ComDustinVossList.
It’d be nice if
Class List = [ComDustinVossList class]; List *aList = List alloc] init]; worked, but it doesn’t.
No, the real solution is language-level namespaces. I’m sure the [[ObjectiveC language nebbishes are already hard at work. When they’ve get it specced out, it can go in GCC.
–DustinVoss
Err, that doesn’t work? I’ve written code which messages Class variables and ivars… why would this particular case not work?
I can imagine that the [List alloc] part would work, but not the List *aList declaration – unless one created a typedef, I suppose. I haven’t tried either part, though, my statement was more of an educated guess.
Under further consideration, I wonder if one could write a macro to take a global name and replace it with a local name? Maybe something like
#define USING (gname, lname) typedef lname gname; static Class lname = [gname class];
although I’m sure I screwed up the syntax somewhere. And this implementation is missing another useful feature of gen-u-ine namespaces: shortened names for a group of classes.
Yeah, sorry guys, sometimes I pick up the wrong idea and run with it. Must be something I ate. But maybe think about this a little more. Who are the ObjectiveC nebbishes? Apple? Is anyone working on this? Where is the real discussion if not here?
Using Cocoa classes as an example, NSArray would be NextStep foundation] array] or maybe just [NextStep array], [[NSView would be NextStep responder] view] or [NextStep view]. - which demands more runtime processing but is also more dynamic - eg you could load a category of [[NextStep and change the class that is returned. Also you don’t have to put up with [NSArray class] anymore just [NextStep array]. You’d always get classes in the same way.
But the other way is NextStep.Array - which is shorter, compile time and demands an extension to the language. Pros and cons to both but I think ObjectiveC benefits from being dynamic - why stop at classes? So I’d think twice before dismissing this idea. – MikeAmy
Ok, I’m making a possibly wrong assumption of designing in terms of protocols rather than interfaces, but:
Class List = [SomeListImplementation class]; // for namespace
.
.
id aList = List alloc] init]; // we know what it does but not exactly what it is - decoupling
or even:
@protocol Thing
@implementation My : BiggerPackage