Ubot Else If Processing

Ubot Studio
One thing you are going to be doing quite a bit is testing for cases using an IF statement. Unfortunately, determining the proper syntax is not easy given that the document is informal. Here we look at the right way of doing IF ELSE processing in Ubot.

In Ubot, the setup is going to look a bit strange if you already are familiar with other programming languages. Take a look at this code:

define $MyTest(#val) {
   set(#retval, 0, "Local")
    if($comparison(#val, "=", 1)) {
        then {
            alert("In case 1")
            set(#retval, 1, "Local")
        }
        else if($comparison(#val, "=", 2)) {
            then {
                alert("In case 2")
                set(#retval, 2, "Local")
            }
}
        else if($comparison(#val, "=", 3)) {
            then {
                alert("In case 3")
                set(#retval, 3, "Local")
            }
}
        else if($comparison(#val, "=", 4)) {
            then {
                alert("In case 4")
                set(#retval, 4, "Local")
            }
        }
else {
alert("In default case")
set(#retval, 0, "Local")
}
    }
    return(#retval)
}
set(#ret, $MyTest(1), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(2), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(3), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(4), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(5), "Local")
alert("Return after ChangeFooey is {#ret}")

First, take note that every test is wrapped around one big IF statement. Typically in C/C++ you would see something like this:

if (expression) {
  do something
}
else if (expression) {
  do something
}
else if (expression)  {
  do something
}
else {
  do something
}

Also, the then statement is redundant but it is used anyway. And finally, to do the boolean test, you invoke the comparison qualifier.

Now why you set it up this way is to back out of testing the value further down the stream of nested else if's. For example, if val above was set to 2, none of the else if's further down will be executed, including the last else.

To see this subtle difference, look at this code:

define $MyTest(#val) {
    set(#retval, 0, "Local")
    if($comparison(#val, "=", 1)) {
        then {
            alert("In case 1")
            set(#retval, 1, "Local")
        }
    }
    if($comparison(#val, "=", 2)) {
        then {
            alert("In case 2")
            set(#retval, 2, "Local")
        }
    }
    if($comparison(#val, "=", 3)) {
        then {
            alert("In case 3")
            set(#retval, 3, "Local")
        }
    }
    if($comparison(#val, "=", 4)) {
        then {
            alert("In case 4")
            set(#retval, 4, "Local")
        }
    }
    return(#retval)
}
set(#ret, $MyTest(1), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(2), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(3), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(4), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(5), "Local")
alert("Return after ChangeFooey is {#ret}")

In this construct, every if is tested making this quite inefficient. For example, if val was set to 1, all the other if's would be executed. One thing you can do to make this much better is to place returns to exit out of the function like so:

define $MyTest(#val) {
    set(#retval, 0, "Local")
    if($comparison(#val, "=", 1)) {
        then {
            alert("In case 1")
            return(#val)
        }
    }
    if($comparison(#val, "=", 2)) {
        then {
            alert("In case 2")
            return(#val)
        }
    }
    if($comparison(#val, "=", 3)) {
        then {
            alert("In case 3")
            return(#val)
        }
    }
    if($comparison(#val, "=", 4)) {
        then {
            alert("In case 4")
            return(#val)
        }
    }
   alert("In default case")
    return(#retval)
}
set(#ret, $MyTest(1), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(2), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(3), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(4), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(5), "Local")
alert("Return after ChangeFooey is {#ret}")

Notice that for the default case I set the return value very early on to a default value. To prove that return is running correctly and exiting out of the function, all values outside the tested range falls through. There is no if else testing. Run this and prove to yourself it works as expected.

One more. For those astute readers, you might be asking, why in your first example, did you nest every test condition within one big IF. Why didn't you do this:

define $MyTest(#val) {
    set(#retval, 0, "Local")
    if($comparison(#val, "=", 1)) {
        then {
            alert("In case 1")
            return(#val)
        }
    }
    else if($comparison(#val, "=", 2)) {
        then {
            alert("In case 2")
            return(#val)
        }
    }
    else if($comparison(#val, "=", 3)) {
        then {
            alert("In case 3")
            return(#val)
        }
    }
    else if($comparison(#val, "=", 4)) {
        then {
            alert("In case 4")
            return(#val)
        }
    }
   alert("In default case")
    return(#retval)
}
set(#ret, $MyTest(1), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(2), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(3), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(4), "Local")
alert("Return after ChangeFooey is {#ret}")
set(#ret, $MyTest(5), "Local")
alert("Return after ChangeFooey is {#ret}")

If you run this, you will notice something strange. On every call after the first, Ubot will bypass all else if's and go to the default case and return 0! What looks normal to the eye for C/C++ programmers will not work. You have to use one of the templates above.


ASO ad


Filed under: