mScriptBox Tutorial
Introduction to If-Then-Else

Written by B0P & blue-elf & pai
Published with permission

Table Of Contents

  1. Introduction
  2. What is if-then-else?
  3. The Syntax
  4. Operators
  5. $iif
  6. Another Example
  7. Common /if Mistakes (Article by blue-elf)
  8. Optimizing your /if's (Article by blue-elf & pai)
  9. Conclusion

1. Introduction  Back to Top

Welcome to this little article where we'll look at one of the key-elements in mIRC scripting, and for that matter, in any programming language; the if-then-else statement.

Required knowledge for this article is identifiers and aliases.


2. What is if-then-else?  Back to Top

If-then-else, or just if-statements is short terms for IF this is true, THEN do this, ELSE do something else. It's a tool that allows us to create code that is dynamically changing depending on several factors such as user input, mIRC version etc, instead of doing one thing and only this one thing. Knowing if-then-else is crucial if you want to become a good coder.


3. The Syntax  Back to Top

IF (v1 OPERATOR v2) THEN { execute this code } ELSE { execute this code }

We've also got a variation of this;

IF (v1 OPERATOR v2) THEN { execute this code }
ELSEIF (v1 OPERATOR v2) THEN { execute this code }
ELSE { execute this code }


4. Operators  Back to Top

An operator is a function or symbol that determines how v1 is compared to v2. Most common is ==, which means is equal to, < meaning is smaller than, > meaning is larger than.
Other commonly used operators are


=== (Case SenSiTive is equal to),
!= (is not equal to),
>= (larger or equal to),
<= (smaller or equal to),
isin (v1 is in v2),
iswm (v1 is a wildcard string in v2),
ison (v1 is on channel v2),
isop (v1 is an op on channel v2),
ischan (v1 is a channel which you are on).

There are others, consult the mIRC helpfile (/help if-then-else) for more info on the subject. You can also do multiple IF statements in one line by using && or || to combine them, && meaning AND (if (statement1) AND (statement2)), || meaning OR (if (statement1) OR (statement2)). Finally, you can negate an operator with placing a ! in front of the operator, thus !isop would mean (v1 is NOT an op on channel v2).

An example

alias hug {
  IF ($1 == $me) { describe $active gives himself a nice hug }
  ELSE { describe $active gives $$1 a nice hug }
}

This code basically says; IF word1 is your own nick, THEN do a /me gives himself a nice hug), ELSE do a /me gives word1 a nice hug. /describe is a command that does a /me to the target, in this case the target is $active, the active window.


5. $iif  Back to Top

This identifier is good for testing what an if statement would return, the syntax is:

$iif(statement is true,do this,else do this)

Try for instance

//echo -a $iif($chan(0) > 0,You're on one or more channels,You're not on any channels) $chan(0)

It will return the number of channels you're on, the if statement thus says; if you're on one or more channels, then echo "You're on one or more channels", else echo "You're not on any channels".

Aside from testing purposes, $iif is good for creating dynamic popups because just as with regular IF statements, you can omit the ELSE part, meaning you can do something like this..:

$iif($me isop $chan,Change topic): { 
  topic $chan $$?="Enter the new topic in # $+ " 
}

This popup would only be available when you're op'd in a channel, allowing you to change the topic of the channel. $iif is also good for producing messages where most of the words are similar, changing only a word or two depending on the user's input or other conditions such as channel modes or awaystatus...


6. Another example  Back to Top

alias bdeg { 
  IF ($2 == c) { RETURN $round($calc(($1 * 1.818) +32),1) }
  ELSEIF ($2 == f) { RETURN $round($calc(($1 - 32) * 0.55),1) }
  ELSE { RETURN Invalid input }
}

This is a custom identifier that converts Celsius degrees to Fahrenheit, and vice versa. Usage is $bdeg(N,C/F), N is the number of degrees to convert, C means that this number is degrees Celsius and should be converted to Fahrenheit, whereas F.... well, you know :)

Looking at line one, the if statement ($2 == c) says that IF word2 is c, THEN return the number in word1 first multiplied with 1.818, then added to 32, then rounded to 1 decimal. This will be the degrees in Fahrenheit. Line two says ELSE IF word2 is f, THEN return the number in word one subtracted with 32, then multiplied with 0.55, then rounded to 1 decimal. With these two lines, we've got ourselves functions that can convert the temperature, the third line says IF NONE of the above is true, THEN return Invalid input, as an error message.

Test this yourself,

//echo -a $bdeg(32,F) should return 0.0,
//echo -a $bdeg(0,C) should return 32.0, and
//echo -a $bdeg(88,F) should return 30.8.


7. Common /if Mistakes (Article by blue-elf)  Back to Top

This article summarizes some common (and not so common) mistakes scripters often make, mostly related to the use of /if.

1. Using >= And <=

Always remember that these operators must be consistent.
This is wrong:
IF ($1 => $2) 
IF ($1 =< $2)
The correct usage is:
IF ($1 >= $2) 
IF ($1 <= $2)

Notice how the equal sign is always last. Also note that, although <> is used for 'not equal' in some languages, in mIRC you must use != to mean 'not equal'.

2. Using isin

Many scripters abuse the isin operator. This leads to a lot of mistakes. For example:

IF ($right($1,4) isin .mp2.mp3)

what the scripter wants is to detect if $1 ends with a .mp2 or .mp3, but it might cause error if the end of $1 is 2.mp, for example. A better way of doing it:

IF ((*.mp? iswm $1) && ($right($1,1) isnum 2-3))
or
IF (($right($1,4) == .mp2) || ($right($1,4) == .mp3))

This is a longer way of doing it but more precise. This can be applied in many places, and although often not significant, it may make a difference in many cases.

3. isin and $istok

Sometimes, isin is used to check if an item is within a list. However, $istok (or $findtok) is often the right way of doing this. For example:

shelp { 
  IF ($1 isin j p plist addpack doffer) { GOTO $1 }
  commands 
}

The above would probably give an error if the user typed /shelp a, something the scripter wasn't looking for. The correct way of doing it would be:

shelp { 
  IF ($istok(j p plist addpack doffer,$1,32)) {
    goto $1 
  }
  commands 
}

The $istok identifier will specifically find only exact words. Note that the '32' is the ascii code for space, which is what separates the 'tokens', or words, here.

4. RETURN and HALT

Although not directly related to /if, this is one of the bigger mistakes many scripters make. Not knowing when to /halt and when to /return can cause many problems.

The return command can also be used to stop processing commands aside from returning values. The difference between the two is as follows:

/halt - stops script processing entirely, and halts any default mIRC behaviors
/return - stops that part of the script only
For example: scripters create aliases that can be called in other parts of the script, for example:
alias do { 
  msg $1 $2- 
  HALT 
} 
on +100:TEXT:*:#:{ 
  do $nick $1- 
  echo $nick sent $1- to you 
}

In the above, the /echo in the on text event will not trigger because it uses a /halt in the alias- which stops the entire script. Whereas, if /return was used, it will continue to echo. thus, in the following:

alias do { 
  msg $1 $2- 
  RETURN 
} 
on +100:TEXT:*:#:{ 
  do $nick $1- 
  echo $nick sent $1- to you 
}

In this, the echo will trigger because /return was used and not a /halt. A common place where /halt is improperly used is, in fact, with /if statements, often as an /else. For example:

alias do { 
  IF ($1 > %blah) { %blah = $1 } 
  ELSE { HALT } 
}

This alias may have the purpose of tracking the highest count of something. However, if the /if fails, the alias halts any script or alias that might have called it, which is probably not what was intended. Instead, a 'RETURN' should have been used, or in this case, simply leave the /else section out.


8. Optimizing your /if's (Article by blue-elf & pai)  Back to Top

This mini-article attempts to demonstrate some tricks and shortcuts that can be used in your /if statements, for speed and compactness.

True And False In /if Statements

/if (value) returns a "true" or "not null" result as long as value is a non-zero value. For example:

%i = 0 
:loop 
INC %i 
IF ($nick(#,%i)) { 
 echo $ifmatch 
 GOTO loop 
}
or
%i = $nick(#,0) 
:loop 
echo $nick(#,%i) 
DEC %i 
IF (%i) { GOTO loop }

With this method, many things can be shortened and optimized. To be specific, /if ($false), /if ($null), and /if (0) will be treated as false, (will not trigger) and anything else will be treated as true. (will trigger)

Another example:

back { 
  away 
  IF ($chan(0) >= 1) { ame is back! }
}

The above could be simplified using the following:

back { 
  away 
  IF ($chan(0)) { ame is back! }
}

Same thing as below:

input { 
  IF ($2 != $null) { echo second argument is $2 }
  ELSE { echo no second argument is given }
}
Simplified as:
input { 
  IF ($2) { echo second argument is $2 }
  ELSE { echo no second argument is given }
}

Note that negative values will not act like 0 values. thus, for example:

%i = -1 
IF (%i) { echo this line will trigger }
As compared with:
%i = 0 
IF (%i) { echo this line will not trigger }
Operator Shortcuts

Some simple simplifications by using different operators-

IF ($left($1,1) == /)

can be simplified with the code below:

IF (/* iswm $1)

In some cases:

IF ($1 isin abcdefghijklmopqrstuvwxyz)

simplified:

IF ($1 isletter)

Instead of:

IF ($me ison %chan)
use:
IF (%chan ischan)
Using Braces

When you write an if statement, you must normally enclose the group of commands in braces:

IF ($nick == $me) { 
  part $chan 
  HALT 
}

However, if you ONLY have one command, the braces are optional, and in fact slow things down ever so slightly:

IF ($nick == $me) { part $chan }
is the same as:
IF ($nick == $me) { part $chan }

although arguably not as nice looking. This one is really a matter of personal preference.

If And Goto

One of the biggest mistakes beginning scripters make is assuming that you MUST have an 'else' statement, or that you have to 'goto' to get to your commands. Commonly seen in scripts-

IF ($me isop $chan) { 
  do stuff 
} 
ELSE { 
  HALT 
}

In most cases, the 'else' section can be completely removed. Or another example, using goto:

IF($me isop $chan) { GOTO first } 
ELSE { GOTO second }
:first 
do stuff 
HALT 
:second 
do stuff

Instead of using gotos like this, just stick the code in the ifs:

IF ($me isop $chan) { 
  do stuff 
} 
ELSE { 
 do stuff 
} 

A final example of an if that doesn't need a goto:

IF ($me !isop $chan) { GOTO end }

This assumes that ':end' is a label at the end of the routine. Instead, just use 'return'- it will end the current alias or remote, without halting any default behaviors or other scripts. (same end effect.)


9. Conclusion  Back to Top

We've in this little article gone through one of the most important features of any coding, the IF-THEN-ELSE statement, and seen how it allows us to create code that reacts conditionally on the environment and the user's input. Note that in the case of single line if statements or execute sections, the ( )'s around the IF statement and the { } around the execute code is not needed, but it's still however generally recommended, as it's supposed to speed up the parsing of such statements and also produces easier-to-read code.

Also note that each code snippet needs the same number of opening { and closing } brackets, missing opening or closing brackets may result in code that's not executed in the correct order, is executed at the wrong time or just wrongfully executed in general. You can often spot this in your remotes if the beginning of an alias, remote or popup definition is indented (not quite to the left of the editor window). To check for bracket mismatches, you may also press the { } button, this will usually take you to the area where a bracket mismatch error occurs.