notoriousb1t

Simple Coding - Part 3: Don't Recycle Variables

When writing a program for readability, the last thing you want to do is recycle variables within functions. It leads to hard to read blocks and makes refactoring more difficult.

"Recycle... you mean reassignment?"

I define recycling as this: reassignment in the same scope for an unrelated reason. At its core, it is an abuse of the ability to reassign variables. Here is an example of recycling a variable in Java:

Recycles

public static List<string> getPermissionArray(Options options) {  
    List<string> output = new ArrayList<string>();

    String temp = "Declined";
    if (options.isAuthorized()){
        temp = "Authorized";
    }
    output.add(temp);

    temp = "Disabled";
    if (options.isEnabled()){
        temp = "Enabled";
    }
    output.add(temp);

    temp = "Readonly";
    if (options.isWritable()){
        temp = "Writable";
    }
    output.add(temp);

    return output;
}

Imagine having to split apart a one thousand line method that recycles variables. It is nightmarish. It is something I have had to do in closed source software more times than I would prefer. I would wish it on my worst enemies because it can be so horrible. Here is the same code refactored to declare new variables each time a different task is performed:

Does NOT Recycle

public static List<string> getPermissionArray2(Options options) {  
    List<string> output = new ArrayList<string>();

    String authText = "Declined";
    if (options.isAuthorized()){
        authText = "Authorized";
    }
    output.add(authText);

    String enabledText = "Disabled";
    if (options.isEnabled()){
        enabledText = "Enabled";
    }
    output.add(enabledText);

    String writableText = "Readonly"
    if (options.isWritable()){
        writableText = "Writable";
    }
    output.add(writableText);

    return output;
}

This is slightly better in my opinion. Not only is it easier to see that you are performing at least three distinct tasks, but it is also easier to refactor because the tasks are not directly connected by a variable. In case you think I'm hating on imperative coding, here are two examples of appropriate reassignment:

Reassigns Variables

string RangeToString(int start, int end) {  
  if (start >= end) {
      return "not valid";
  }
  var builder = "";
  for (var i = start; i < end; i++) {
      builder += i;
  }
  return builder;
}
def range_to_string(start, end):  
    if start >= end:
        return "not valid"
    builder = ""
    for i in range(start, end):
        builder += str(i)
    return builder

This is generally okay. It builds out a string by reassigning the current value using the shorthand += operator. You would probably never need a function to output a range this way, but you get the point.

Final Thoughts

I have found that recycling in code is a good indication that the same logic is being repeated over and over in the code. This kind of code begs to be refactored. Duplication is not the devil, but it can be evil. The first example in this post could be refactored down significantly and would be easier to understand.