4

I'll preface this with I don't know if anyone else who's been programming as long as I have actually has this problem, but at the very least, the answer might help someone with less xp.

I just stared at this code for 5 minutes, thinking I was losing my mind that it didn't work:

    var usedNames = new HashSet<string>();
    Func<string, string> l = (s) =>
        {
            for (int i = 0; ; i++)
            {
                var next = (s + i).TrimEnd('0');
                if (!usedNames.Contains(next))
                {
                    return next;
                }
            }
        };

Finally I noticed I forgot to add the used name to the hash set.

Similarly, I've spent minutes upon minutes over omitting context.SaveChanges().

I think I get so distracted by the details that I'm thinking about that some really small details become invisible to me - it's almost at the level of mental block.

Are there tactics to prevent this?

update: a side effect of asking this was fixing the error it would have for i > 9 (Thanks!)

    var usedNames = new HashSet<string>();
    Func<string, string> name = (s) =>
        {
            string result = s;
            if(usedNames.Contains(s))
                for (int i = 1; ; result = s + i++)
                    if (!usedNames.Contains(result))
                        break;
            usedNames.Add(result);
            return result;
        };
4
  • 1
    Why are you calling .TrimEnd('0')? What happens when you get up to 10?
    – SLaks
    Oct 31, 2011 at 17:28
  • 2
    Kind of like asking: Is a way to prevent me from doing subtraction when I meant to do addition?
    – mikerobi
    Oct 31, 2011 at 17:28
  • 3
    I find explaining the algorithm to someone else, will quickly make me realise where I've gone wrong.
    – Ray
    Oct 31, 2011 at 17:31
  • @Slaks - good point - its so the first iteration doesn't doesn't append a number - it won't make it to 10 :) Oct 31, 2011 at 17:31

4 Answers 4

6

A unit test likely would've / should've caught this omission.

Assert.AreEqual("NEXT", obj.GetNextName("NEXT"));
Assert.AreEqual("NEXT1", obj.GetNextName("NEXT"));

It would also catch the likely bug you'll have when i = 10.

...
Assert.AreEqual("NEXT9", obj.GetNextName("NEXT"));
/* your TrimEnd call could be a bug */
Assert.AreEqual("NEXT10", obj.GetNextName("NEXT"));  

Test-driven development is proactive by its definition. In your example, you would immediately see that it wasn't working as designed and you would get feedback as to what it was returning.

3

You could ask someone else to look over your code.

2

Experience is the best defense here.
Over time, you should become more adept at spotting these omissions from the observed behavior.
(You should also become more adept at not making them in the first place)

Stepping through the code line-by-line in the debugger should also highlight what's missing.

2

I personally find it helpful to describe my methods in comments before writing the implementation code. That way, if I forget something, or if someone else picks it up in two weeks time, they will know what was 'supposed' to happen and should be able to implement it themselves without needing to some and ask me!

E.g

MyMethod() {
    //setup vars

    //perform complex function

    //set flag for something or other

    //save changes
}

It won't prevent the 'I've made an error in the algorithm' type issues, unless you really go low level with the commenting, but it should prevent the 'forgotten to save changes' type errors.

4
  • its funny, i stopped doing that when i got wind that hip developers don't comment every line - but it's probably something that would help me to go back to Oct 31, 2011 at 17:49
  • 2
    There is a fine line between commenting things for the sake of it and adding useful annotation, but I try to think of it like a comment interface, if you will! That way when I satisfy my comment contracts I may remove them, but sometime they are useful for others to see what was going through my mind at the time!
    – dougajmcdonald
    Oct 31, 2011 at 18:12
  • 1
    @Gabriel Also, nothing personal as I'm aware you're not making this statement. But from a personal perspective I resent the arrogance of certain developers who make comments like 'A good developer should just 'understand the code'' and the such like, in my opinion, anything which makes code easier to understand when you come back to it in say 2 years time, is worth adding in. It should save time/money in the long run. This is especially true in team environments when experience levels in certain areas may vary vastly.
    – dougajmcdonald
    Oct 31, 2011 at 18:15
  • You picked up on the undercurrent of my comment - I jokingly think to myself that "EDD", ego driven development, will be the next big thing :) Oct 31, 2011 at 18:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.