Recently Oliver’s blog post ‘Shuffling an NSArray‘ came across my twitter feed. I’m not sure I followed the link with the intention of being critical, but after reading, I felt the need to make a couple of points. Namely, a fairly staunch opinion that in it’s current form, Oliver’s -(NSArray *)shuffled method is an example of poor naming choice. I realize that the original post was intended to showcase the ability to extend existing classes with categories (a powerful and worthwhile concept to understand). However, take into consideration that many developers new to a language will copy and paste code snippets without fully understanding them, and the importance of using proper convention in code examples becomes very clear.
What’s in a name?
Cocoa is full of naming conventions, a characteristic that has grown to be one of the primary reasons for my love of developing with it. Apple’s own documentation (“Coding Guidelines for Cocoa”) indicates that naming conventions are important for keeping your interfaces consistent and clear. According to Scott Stevenson at CocoaDevCentral, “Naming consistency isn’t extra credit, it’s an essential part of being a great Cocoa programmer”. The ability to develop cocoa applications at an accelerated pace can largely be credited to the fact that understanding method behaviors is almost always completely evident by simply looking at it’s name.
What’s wrong with using “shuffled”, isn’t that what is happening?
My primary complaint about extending NSArray with a method named ‘shuffled’ is that it is quite unclear and somewhat misleading. Without poring over the implementation, it is not immediately obvious what the expected behavior might be, or what objects will be molested and/or returned. Apple indicates that the name of methods representing an action taken by an object should be started with a verb. Shuffled, being a verb, suggest that the receiving object, in this case an NSArray, is going to shuffle. The obvious problem being that, NSArray is immutable – how is it possibly going to be shuffled?
In part two of his article “Cocoa Style for Objective-C” Scott Stevenson touches on naming methods that return objects. As he indicates, there are three basic formats that should be followed .
[object/class thing+condition]; [object/class thing+input:input]; [object/class thing+identifer:input];
or, when wanting to return a variation on a value
[object adjective+thing]; [object adjective+thing+condition]; [object adjective+thing+input:input];
Applying these guidelines, we can see that we are missing one key factor, and that is the THING that we are returning (in this case an NSArray). We should probably be using something closer to -(NSArray *)arrayByShufflingContents or -(NSArray *)shuffledArray. The commonality between the two being that they clearly indicate the thing we will be returning. A very simple change – but one that makes our method much more clear, and lets other developers know we will be returning a new array, not a pointer to the same object we have told to shuffle.
Reviewing the Foundation classes, we can also see that there is an established precedent for naming methods that change the contents of immutable objects.
All of these clearly define the type of object they will return, as well as the condition, input, or adjective describing the variant.
Having read all of that, it might seem like I’m arguing minutia. What difference does adding Array to the end of the method really make? The return type of the method definition is NSArray, and we’re extending NSArray – we can obviously deduce that we’re getting a new object back, right? The major point I’m trying to make is that I should never have to deduce what a method does, and I should rarely have to deduce what a method returns. In the overwhelming majority of cases, it should be almost entirely clear without referencing a minimal amount of documentation.
To continue on the idea of extending NSArray and code cleanliness, I’d like to suggest the form I feel adds the desired functionality, in the clearest possible way. I present, the class method.
I’d venture to guess that every cocoa developer has used class methods, but if you aren’t sure what I’m talking about, this new method would be called similar to the following:
Using this, it is blissfully clear to any developer implementing our category, or reviewing our code, that arrayByShufflingContentsOfArray: is creating a new instance of an NSArray by shuffling the contents of the array that is passed to it.
As a relatively new Cocoa developer myself, I welcome any questions, comments or criticism regarding anything I’ve outlined here – hell, any cocoa related topics for that matter. My cocoa, iphone, and misc ramblings can be heard, 140 characters at a time on twitter. Feel free to get in touch – @jetskier79