[Adium-devl] Early Returns and the Coding Style Docs
David Smith
catfish.man at gmail.com
Tue Mar 28 03:46:02 UTC 2006
Hi everyone,
I was looking at a block of code, and noticed that using early
returns could make it, imo, much more readable. Basically, less
indentation depth, less masses of closing braces to try to match up,
and less scoping oddities (like having to declare replacementMessage
outside the if). However, our coding guidelines say to avoid early
returns. I can see the reasoning behind it (single exit point
functions do have some appeal), but I think we make too many sacrifices.
I do agree with the guidelines in that stuff like while() { while()
{ if() { return foo; } } } return bar; should be avoided though. I
see early returns as mostly being useful for bypassing method bodies
when preconditions aren't met, such as below.
What do people think of this? Am I in a minority here in liking
early returns? (I know I'm a minority in liking braces on their own
lines, I'm not even trying to argue that one anymore ;) )
Before:
- (NSAttributedString *)filterAttributedString:(NSAttributedString *)
inAttributedString context:(id)context
{
NSMutableAttributedString *replacementMessage = nil;
if (inAttributedString) {
NSRange linkRange = NSMakeRange(0,0);
unsigned index = 0;
unsigned stringLength = [inAttributedString length];
replacementMessage = [inAttributedString mutableCopy];
while (index < stringLength) {
if (![replacementMessage attribute:NSLinkAttributeName
atIndex:index effectiveRange:&linkRange]) {
/* If there's no link at this index already, process it via the
hyperlinkScanner to see if there should be one.
* We don't process existing links because (a) it would be
duplicative effort and (b) we might mess up a link which had
* a linkable item within its text, such as "Check out the new
story at adiumx.com" linked to an adiumx.com page.
*/
NSAttributedString *replacementPart = [hyperlinkScanner
linkifyString:[inAttributedString
attributedSubstringFromRange:linkRange]];
[replacementMessage replaceCharactersInRange:linkRange
withAttributedString:replacementPart];
stringLength -= linkRange.length;
linkRange.length = [replacementPart length];
stringLength += linkRange.length;
}
// increase the index
index += linkRange.length;
}
}
return (replacementMessage);
}
After (as well as a bit of other cleanup):
- (NSAttributedString *)filterAttributedString:(NSAttributedString *)
inAttributedString context:(id)context
{
if(!inAttributedString) return nil;
NSMutableAttributedString *replacementMessage = [inAttributedString
mutableCopy];
NSRange linkRange = NSMakeRange(0,0);
unsigned stringLength = [replacementMessage length];
for (int i = 0; i < stringLength; i += linkRange.length) {
if ([replacementMessage attribute:NSLinkAttributeName atIndex:index
effectiveRange:&linkRange])
continue;
/* If there's no link at this index already, process it via the
hyperlinkScanner to see if there should be one.
* We don't process existing links because (a) it would be
duplicative effort and (b) we might mess up a link which had
* a linkable item within its text, such as "Check out the new
story at adiumx.com" linked to an adiumx.com page.
*/
NSAttributedString *replacementPart = [hyperlinkScanner
linkifyString:[inAttributedString
attributedSubstringFromRange:linkRange]];
[replacementMessage replaceCharactersInRange:linkRange
withAttributedString:replacementPart];
stringLength -= linkRange.length;
linkRange.length = [replacementPart length];
stringLength += linkRange.length;
}
return replacementMessage;
}
There's also a side issue in that *somehow* replacementMessage =
[inAttributedString mutableCopy]; is failing, claiming that it's
calling -initWithAttributedString: with a nil argument. Dunno how
that happens.
David Smith
More information about the devel
mailing list