Skip to content

Instantly share code, notes, and snippets.

@anselm
Created January 15, 2016 18:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anselm/5b5398c10b24419bd031 to your computer and use it in GitHub Desktop.
Save anselm/5b5398c10b24419bd031 to your computer and use it in GitHub Desktop.
A small bit of kvetching...
Imagine in Shakespeare if a sonnet didn't hew towards the core message but instead had you hold all the loose blocks of marble in working memory.
My mistresses eyes are like the sun in no way, but in the way they are not like the sun so is her hair like wires, and in the way they are like the sun there is nothing further to remark upon.
By a similar quality it bugs me when early out conditions are deferred to the end of a code block. For me this is probaby a carry over from working in assembler. In early programming environments there was both a computational and cognitive cost to jumping around a block of other code prior to ceding control. Modern compilers optimize this away but there's still a cognitive burden to having to hold a larger model in mind. If you think of a piece of code as a tree of branching possibilities then it makes sense to whittle away those branches as quickly as possible so that you're left with the minimum functionality needed to close out the responsibility of that piece of code. By writing code in such a way that you don't reach closure till the end you create more cognitive burden. It's arguable that forcing a reader to maintain a larger cognitive burden is a plus. The reader should be able to maintain the cognitive load of the single most complex piece of code. But I prefer the simplicity of presenting the pieces in a way that a reader can discard the extraneous materials and focus on the core functionality. So often much of the preamble is discarding the edge cases.
Here's an example of a piece of code prior to me refactoring it and after refactoring. Which is more clear?
// BEFORE a bit of refactoring for simplicity
- (BOOL)loadAndActivateImageTrackerDataSet:(NSString*)dataFile {
NSString *stringURL;
NSURL *url;
NSData *urlData;
stringURL = @"http://somefile.com/blah.xml";
url = [NSURL URLWithString:stringURL];
urlData = [NSData dataWithContentsOfURL:url];
if ( urlData ) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"somefile.xml"];
[urlData writeToFile:filePath atomically:YES];
dataFile = filePath;
}
stringURL = @"http://somefile.com/blah.dat";
url = [NSURL URLWithString:stringURL];
urlData = [NSData dataWithContentsOfURL:url];
if ( urlData ) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"blah.dat"];
[urlData writeToFile:filePath atomically:YES];
}
NSLog(@"loadAndActivateImageTrackerDataSet (%@)", dataFile);
BOOL ret = YES;
dataSet = NULL;
// Get the QCAR tracker manager image tracker
QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
QCAR::ObjectTracker* objectTracker = static_cast<QCAR::ObjectTracker*>(trackerManager.getTracker(QCAR::ObjectTracker::getClassType()));
if (NULL == objectTracker) {
NSLog(@"ERROR: failed to get the ObjectTracker from the tracker manager");
ret = NO;
} else {
dataSet = objectTracker->createDataSet();
if (NULL != dataSet) {
NSLog(@"INFO: successfully loaded data set");
// Load the data set from the app's resources location
if (!dataSet->load([dataFile cStringUsingEncoding:NSASCIIStringEncoding], QCAR::STORAGE_ABSOLUTE)) {
NSLog(@"ERROR: failed to load data set");
objectTracker->destroyDataSet(dataSet);
dataSet = NULL;
ret = NO;
} else {
// Activate the data set
if (objectTracker->activateDataSet(dataSet)) {
NSLog(@"INFO: successfully activated data set");
}
else {
NSLog(@"ERROR: failed to activate data set");
ret = NO;
}
}
}
else {
NSLog(@"ERROR: failed to create data set");
ret = NO;
}
}
return ret;
}
// AFTER a bit of refactoring for clarity - could use more clarity even
- (BOOL)loadAndActivateImageTrackerDataSet {
NSString *stringURL;
NSString *dataFile = nil;
NSURL *url;
NSData *urlData;
stringURL = @"http://somefile.com/blah";
url = [NSURL URLWithString:stringURL];
urlData = [NSData dataWithContentsOfURL:url];
if (!urlData) {
return NO;
}
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"blah.xml"];
[urlData writeToFile:filePath atomically:YES];
dataFile = filePath;
}
stringURL = @"http://somefile.com/blah2";
url = [NSURL URLWithString:stringURL];
urlData = [NSData dataWithContentsOfURL:url];
if (!urlData) {
return NO;
}
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"blah.dat"];
[urlData writeToFile:filePath atomically:YES];
}
NSLog(@"loadAndActivateImageTrackerDataSet (%@)", dataFile);
dataSet = NULL;
// Get the QCAR tracker manager image tracker
QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
QCAR::ObjectTracker* objectTracker = static_cast<QCAR::ObjectTracker*>(trackerManager.getTracker(QCAR::ObjectTracker::getClassType()));
if (NULL == objectTracker) {
NSLog(@"ERROR: failed to get the ObjectTracker from the tracker manager");
return NO;
}
dataSet = objectTracker->createDataSet();
if (dataSet == NULL) {
NSLog(@"ERROR: failed to create data set");
return NO;
}
NSLog(@"INFO: successfully loaded data set");
// Load the data set from the app's resources location
if (!dataSet->load([dataFile cStringUsingEncoding:NSASCIIStringEncoding], QCAR::STORAGE_ABSOLUTE)) {
NSLog(@"ERROR: failed to load data set");
objectTracker->destroyDataSet(dataSet);
dataSet = NULL;
return NO;
}
// Activate the data set
if (!objectTracker->activateDataSet(dataSet)) {
NSLog(@"ERROR: failed to activate data set");
return NO;
}
NSLog(@"INFO: successfully activated data set");
return YES;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment