views:

669

answers:

11

I recently came upon some code filed with the following

} catch (FooException e) {
 //do something
} catch (BarException e) {
 //do something
} catch (Exception e) {
  throw e;
}

which is easily re-written as

} catch (FooException e) {
 //do something
} catch (BarException e) {
 //do something
}

and

if (!(flag == false))

which is easily rewritten as

if (flag)

What are some of the most common junk code examples and the easier/clearer/less verbose replacement code.

+4  A: 

http://thedailywtf.com/ has loads of examples of bad code like this.

ceejayoz
+13  A: 
if (x == 1)
  return true;
else
  return false;

Rewrite:

return (x == 1);
fbinder
Rewrite: return x == 1;
Greg Beech
This is the most common thing, can't believe I didn't think of it at the time. Sadly, I see this rewritten as "return x == 1 ? true : false;" all the time
sal
+4  A: 

Your examples do different things.

} catch (Exception e) {
  throw e;
}

Will discard the original exception, create a new exception in the context of the currently-executing method, and throw that. The original exception will be lost. This is rarely what you want to do, your re-written example is better.

Dour High Arch
In what language? I see no new exception being created here.
Ken
In c#. It doesn't really create a new exception, but it does blow away the original exception's context, esp. the stack trace.
Greg D
+1 -- the original exception handling was a WTF and the rewrite changes what is thrown. However, in the right context, the original may make sense.
Austin Salonen
Wow, you're right. Microsoft's own "try-catch" page shows using "throw (e);", and then mentions "throw;" only in the context of "the exception currently handled by a parameter-less catch clause".(There's a "Community Content" section where a Peter Ritchie lists guidelines, the very last of which is "Do not rethrow by throwing the same exception object. This causes the stack trace for the original exception to be lost".)So it's true, but basically impossible to find in the docs unless you think to go looking for it.
Ken
+1  A: 

Take a look at all of the rules that static code analysis tools like PMD and Findbugs use.

matt b
The problem with that being that there are so many in the findbugs library that its like browsing the phone book.
sal
A: 

Ternary operator

dim str
if(predicate)
  str = "a"
else
  str = "b"
end

Rewrite

String str = iff(predicate, "a", "b")
hypoxide
I'd rewrite that as String str = "a", personally. :b
Chad Birch
Good point. See edit ;P
hypoxide
Your "ternary operator" is a function call. If that is in e.g. C# or Java or any other language using eager evaluation of function parameters the behavior might be different from if/else.
0xA3
that's a VB ternary operator, friend
hypoxide
Not quite. IIf is a library function with three arguments. Both truepart *and* falsepart are always evaluated (in contrast to if/else and ternary operator) where only one of them is evaluated. In VB 9.0 there is a true ternary operator named `if` (see http://bartdesmet.net/blogs/bart/archive/2007/08/31/visual-basic-9-0-the-if-ternary-operator.aspx)
0xA3
(continued): In fact, the rewrite is likely to introduce problems. Consider the following (line breaks are missing here): if not obj is nothing then obj.DoSomething else obj = new MyObject(). When rewritten it will throw a NullReferenceException.
0xA3
+1  A: 

Initialization with value when in case of null a default is used instead.

Foo x = null;    
if(something != null) {
  x = something;
} else {
  x = default;
}

=>

Foo x = something != null ? something : default;

In languages where if is an experssion:

Foo x = if(something != null) something else default;
egaga
I'd much rather see the original. Your rewritten version is pretty hard to decode.
Chad Birch
If this is C# a more concise version would be to use the null coalescing operator: Foo x = something ?? default.
Greg Beech
Why not: Foo x = something; if (x == null) x = default;
Grant Wagner
Chad: but it doesn't set "x=null" unnecessarily.
Ken
Grant: that would prevent x being a immutable reference, and immutability is a recommended use if no reason to do otherwise.
egaga
Whatever else you may say about Perl, you have to like it's defined-or operator (`//`), which was invented for this job: `$foo = something // default;`
Chris Lutz
A: 
(bColour)?bColour=false:bColour=true; //could have done (i%2!=0)?bColour=true:bColour=false;

instead of:

bColour = !bColour; //could have done bColour=(i%2!=0);

Yes, the comment on the original mess was actually in the code, so I corrected it too.

Grant Wagner
I don't like seeing assignments after the '?' in ternary expressions either
Michael Haren
+3  A: 

Old-style C string manipulation seems to be a bugaboo for a lot of people.

I've got two right here in my emacs buffer. Example 1:

strcpy(label, "\0");
strcpy(comm1, "\0");   //!!!20060818 Added protective code for missing nulls
strcpy(comm2, "\0");
strcpy(dir, "\0");

This is basically calling a routine with all the associated overhead just to do:

label[0] = '\0';

Here's an even more fancy variant later on in the code:

strncpy(inq.szComment, "\0", 1);

Again, this is just a really elaborate and slow way to assign the nul character '\0' to the first element of inq.szComment.

Example 2:

// This is always good for string operations, but may not be necessary.
strcat(RpRecPrefix, "\0");
strcat(RpCircPrefix, "\0");
strcat(RpEventPrefix, "\0");
strcat(RpFdk, "\0");
strcat(RpAic, "\0");
strcat(RpDcl, "\0");
strcat(RpVis, "\0");
strcat(RpSnd, "\0");
strcat(RpL3Fsi, "\0");
strcat(RpStartState, "\0");
strcat(RpContRun, "\0");

These find the null at the end of the first string parameter, and then do nothing. I can't tell if the author thought he was protecting against not having a terminating nul, or if he thought this would somehow tack an extra nul at the end. Either way, he was wrong.

OK. Here's my personal favorite.

  if ( *pnFrequency == 1 ) {
      sprintf(szLogMsg, "Write to disk speed = %d bytes/sec at 1 Hz",
              *pliWriteRate);
  }
  else if ( *pnFrequency == 2 ) {
      sprintf(szLogMsg, "Write to disk speed = %d bytes/sec at 2 Hz", 
              *pliWriteRate);
  }
  else if ( *pnFrequency == 4 ) {
      sprintf(szLogMsg, "Write to disk speed = %d bytes/sec at 4 Hz", 
              *pliWriteRate);
  }
  else if ( *pnFrequency == 10 ) {
      sprintf(szLogMsg, "Write to disk speed = %d bytes/sec at 10 Hz", 
              *pliWriteRate);
  }
  else if ( *pnFrequency == 20 ) {
      sprintf(szLogMsg, "Write to disk speed = %d bytes/sec at 20 Hz", 
              *pliWriteRate);
  }
  else if ( *pnFrequency == 40 ) {
      sprintf(szLogMsg, "Write to disk speed = %d bytes/sec at 40 Hz", 
              *pliWriteRate);
  }
  else if ( *pnFrequency == 60 ) {
      sprintf(szLogMsg, "Write to disk speed = %d bytes/sec at 60 Hz", 
              *pliWriteRate);
  }
  else { // above frequencies used for analysis
      sprintf(szLogMsg, "Write to disk speed = %d bytes/sec", *pliWriteRate);
  }

Note that the value of *pnFrequency we check for in every branch is identical to the value hard-coded into its sprintf, and that is the only difference in any and every branch. The whole thing should have been:

sprintf(szLogMsg, "Write to disk speed = %d bytes/sec at %d Hz", *pliWriteRate,
        *pnFrequency);

I just simply can't imagine how this file got to be 12,000 lines long...

T.E.D.
Hang onto that file, you've got some real winners there.
Marc Bernier
+1  A: 
List<String> list = new ArrayList<String>();
list.add("Foo");
list.add("Bar");

=>

List<String> list = Arrays.asList("Foo", "Bar");

In which case list would be immutable. If you want to achieve the same with a mutable list, create a util class:

public CollectionUtils {
  public static List<T> createMutableList(T ... elements) {
    List<T> list = new ArrayList<T>();

    for(T elem : elements) list.add(elem);

    return list;
  }
}

And then you can use it:

import static CollectionUtils.createMutableList;    
List<String> list = createMutableList("Foo", "Bar");
egaga
Not exactly the same thing. You can't add or remove elements from the Arrays.asList version (which of course might be an improvement, but still...).
Michael Myers
That's a good point, but people use the first way even when not needed.
egaga
+3  A: 

Before Linq:

for each listItem1 in list1
  for each listItem2 in list2
    if listItem1.value1 = listItem2.value2
     listSimilarItems.add(listItem1)
  end
end

After Linq:

listSimilarItems = (from items in list1 where list1.value1 = list2.value2).tolist
hypoxide
+6  A: 

On the web side of programming, something I frequently see is the use of CSS rules like the following:

<div class="red">Error message!</div>

With the red style defined as:

red { color: #f00; }

Well, that's stupid. And then when they decide that the error message should also have a yellow background you see this:

<div class="red yellowback">Error message 2.0!</div>

Or even worse:

<div class="yellowback">
  <h1 class="red">Error message 3.0!</h1>
</div>

The proper way to use CSS is to construct your HTML in a semantically correct way first, and then identify each part with either 'id' or 'class' names, so that you can target each section and apply the appropriate rules. For example:

<div id="errormessages">Error message!</div>

Instead of a <div> you could make it a paragraph, so that it stand's out even without styles (e.g., when using a text browser):

<p id="errormessages">Error message!</p>

And the CSS rule:

#errormessages {
    color: #f00;
    background-color: #ff0;
}
Jorge Gajon