0

Let's say we have two ifs that depend on each other:

if var exists {
    if var is array {
        //Do stuff with var
    } else {
        //Resolve the problem
    }
} else {
    //Resolve the problem in the exact same way as above
}
//Continue execution with the assumption that var is in the appropriate state

How can I refactor this to remove the duplicated code without using gotos or functions/methods?

9
  • 4
    Use goto of course!
    – svidgen
    Aug 7, 2014 at 3:09
  • 4
    ... why do you want to avoid a function? That's one of the things they're meant to do - keep you from writing the same thing multiple times. As the accepted answer shows it can be mitigated here, but the fact that you're avoiding a reasonable tool is somewhat troubling. Aug 7, 2014 at 4:21
  • 2
    if var exists && var is array
    – user253751
    Aug 7, 2014 at 5:37
  • 1
    @Clockwork-Muse Sometimes the else block(s) might contain nothing more than "var = someFunction('String', 1)" which, when turned into a function, makes less sense. Why have such a small function when you can inline the whole thing? My other reason for asking is because it seemed like I was missing something. Something about the way I structured my control flow felt wrong and I couldn't figure what the problem was. And it didn't seem like a function would fix it, it would just patch the problem. Aug 7, 2014 at 6:12

3 Answers 3

12

Am I missing something more complicated here, or shouldn't this just be:

if var exists and var is array {
    //Do stuff with var
} else {
    //Resolve the problem
}

//Continue execution with the assumption that var is in the appropriate state

The check for if var exists will short-circuit and fall through to the else resolution block if it evaluates to false.

3
  • +1 I'm the author of the other answer (programmers.stackexchange.com/a/252569/61852) but this one is better, unless we are missing something. Aug 7, 2014 at 1:57
  • Thanks! I noticed this could be a solution but I had heard rumors that it's actually faster on modern systems to NOT short circuit the operation and I was nervous about relying on it. On reading your answer I realized that that might be a bit ridiculous. Aug 7, 2014 at 3:30
  • @TrentonMaki, short-circuting can be slower yes. But in your case, you just wrote your own short circuiting logic. That's certainly not faster. Aug 27, 2014 at 15:54
1

If you don't mind "do stuff with var" runs every time:

if var does not exist {
    //Resolve the problem
}

if var is array {
    //Do stuff with var
} 
//Continue execution with the assumption that var is in the appropriate state

If you don't want "do stuff with var" to run every time (as in original code):

if var does not exist {
    //Resolve the problem
    flag = true
}

if var is array && flag == true {
    //Do stuff with var
} 
//Continue execution with the assumption that var is in the appropriate state
4
  • if var exists but is not an array, it will not execute "resolve the problem".
    – Florian F
    Aug 27, 2014 at 13:20
  • @FlorianF That's exactly what should happen. Take a look at the original code in the question. Aug 27, 2014 at 13:36
  • Hm... I don't see it. The original code says: if var is array {...} else { //Resolve the problem}. So if it is not an array, it executes { //Resolve the problem }.
    – Florian F
    Aug 27, 2014 at 13:50
  • @FlorianF You're right, this code doesn't handle the case where var isn't an array. Aug 27, 2014 at 19:33
1

Assuming the tests cannot be joined in one expression I would write:

bool ok = false;
if var exists {
    if var is array {
        //Do stuff with var
        ok = true;
    }
}
if (!ok) {
    //Resolve the problem
}
//Continue execution with the assumption that var is in the appropriate state
1
  • I did consider this as an option but I don't like polluting the context with one-off variables. But there might be situations where this is the best option, say where the checks are non trivial or you need to do something in between the ifs (assuming all other things being equal). Aug 27, 2014 at 19:28

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