mScriptBox Tutorials
$eval Identifier

Written by FiberOPtics
Published with permission.

Table Of Contents

  1. Introduction
  2. First Steps
  3. The Usage of $eval
  4. Important Notes
  5. Example: A Swear Kicker
  6. Conclusion

1. Introduction  Back to Top

Eval is an identifier which is handy to control the level of evaluation of the contents that you pass it. Whilst this may seem very vague, it does serve its purpose in a lot of cases.

We'll first explain the regular $eval, and later on the $(...) eval construct which can be used in events with a matchtext.


2. First Steps  Back to Top

Let's start out with an example which on one hand already uses $eval, and on the other hand will help us explain what $eval does.

In your mIRC type the following line, and make sure the double // is preserved:


//set -s %ev.a $eval(%ev.b,0) | set -s %ev.b $eval(%ev.c,0) | set -s %ev.c $eval(%ev.d,0) | set -s %ev.d 100
This will set the following variables in your variables list:
(You can check this by pressing ALT+R and navigating to the Tab "Variables")

     %ev.a %ev.b
     %ev.b %ev.c
     %ev.c %ev.d
     %ev.d 100
Note: When you issue the above command in your mIRC, you will actually see what variables are set to what value, because we've used the -s flag.


3. The Usage of $eval  Back to Top

The level is a number from zero or higher, which tells mIRC how many times to evaluate the input. In the example that you typed, I used $eval(...,0) which means: do not evaluate the input.

Why did we use $eval(%ev.b,0)?
As you may or may not know, when passing a parameter to a variable in mIRC, it is evaluated (at least in scripts, or when using double // in an editbox, as we did)

Therefore when issuing //set %ev.a %ev.b, the %ev.b would have evaluated to $null (nothing), since we'll assume that we don't have that variable in our variables list).

But we wanted to have the actual string "%ev.b" as value, in other words, we don't want the variable to evaluate, therefore we use $eval with level 0. Now, let's take a closer look at the example. Type the following things:


    //echo -a Level 0: $(%ev.a,0)
    //echo -a Level 1: $(%ev.a,1)
    //echo -a Level 2: $(%ev.a,2)
    //echo -a Level 3: $(%ev.a,3)
    //echo -a Level 4: $(%ev.a,4)
The results will be:
Level 0 - $eval(%ev.a, 0):
Do not evaluate the input string.

Result: %ev.a
Level 1 - - $eval(%ev.a, 1):
Evaluate the input string once:
First, evaluates %ev.a, which has as value %ev.b

Result: %ev.b
Level 2 - $eval(%ev.a, 2):
Evaluate the input string twice:
First, evaluate %ev.a to %ev.b
Second, evaluate %ev.b to %ev.c

Result: %ev.c
Level 3 - $eval(%ev.a, 3):
Evaluate the input string three times:
First, evalute %ev.a to %ev.b
Second, evalute %ev.b to %ev.c
Third, evaluate %ev.c to %ev.d

Result: %ev.d
Level 4 - $eval(%ev.a, 4):
Evaluate the input string four times
Same steps as for level 3 evaluation, with result being %ev.d
Fourth evaluation, returning the value of %ev.d being 100

Result: 100

What we have now seen is the main function of $eval, it is to specify the level of evaluation of whatever you input.


4. Important Notes  Back to Top

  • $eval(input,level) can be used as $(input,level)
    It is simply a shorter notation, which provides the same functionality.
  • $eval(input,0) is the same as $eval(input,)
  • $eval(input,1) == $eval(input) == $(input)
    Note that evaluation in mIRC is usually by default of level 1.
    Some examples:
    //echo -a $me

    Because of the double //, it evaluated $me to your nickname. This is evaluation of level 1.

    //var %a = 5 | echo -a %a
    It echoed the value of %a, because %a was evaluated one level, to 5. In other words, in the echo, %a is the same as $(%a,1).

  • $(...) is a special form of $eval, which is used as matchtext in events. Let's show an example:
    
    ON *:TEXT:$($+(*,$me,*)):#:{
        echo -a $nick said: $matchkey on channel: # wich contained your nickname: $me
    }
    

    As you can see we used the $eval of level 1 in its special form of $() to make the $+() and $me identifiers evaluate. Note that you cannot use $eval in the matchtext, only $(..)

  • As stated, you can use $eval(input,0) to force the input not to be evaluated.

    This is particularly handy, when passing parameters to commands which evaluate contents twice. We're thinking for example of /timer and /scon or /scid -a... It is out of the scope of this tutorial to start explaining double evaluation, and how $eval can come in handy. You should just know that once you advance in scripting, you will find out that $eval is more handy than just letting dynamic variables evaluate easily.

  • Note that the examples and explanation throughout this tutorial use variables to show $eval's functionality. Be aware that this evaluating will occur on any string you input, which includes identifiers.
    An example: //echo -a $!!me - $eval($!!me,2) - $eval($!!me,3)

    Because of the double //, it evaluated $!!me to $!me. This is evaluation of level 1.
    $eval($!!me,2) evaluated first to $!me, second to $me
    $eval($!!me,3) evaluated first to $!me, second to $me, third to FiberOPtics

  • 5. Example: A Swear Kicker  Back to Top

    Note, this example may look hard for a beginner in scripting. The main idea to focus on is the way $eval is used.

    Suppose you are making a swear kicker. It will kick a person who is swearing on a channel that you are oped in. However, you want to make a distinction between the nick, network and the channel that the swear was said in.

    I'll explain a little further:

    Say a person named Rocko, on network 1 swears in channel #c1.
    I could set a variable like: //set %swear $+ Rocko true, to denote that Rocko has sweared.
    But what if on another network there is another Rocko, which is not the same person? He would be accused of having used swear words, with possible repercussions following, like a ban.

    So we will create a dynamic variable, which will show us how $eval can come in handy.
    //inc %swear $+ $nick $+ $cid $+ $chan
    or shorter
    //inc $+(%,swear,$nick,$cid,$chan)

    This would for example set the variable: %swearRocko2#c1 to value 1. ($cid is a network identifier, /help $cid)

    $eval comes into play when we want to check the value of the dynamic variable.

    To check the value of the dynamic variable with parameters: Rocko for $nick, 2 for $cid, and #c1 for $chan, we cannot just do something like this:
    //echo -a $+(%,swear,Rocko,2,#c1)
    as it would simply echo to us: %swearRocko2#c1

    Instead we want to see the value of the variable, which is why we need to enforce one level of evaluation further, which $eval will do for us.
    //echo -a $eval($+(%,swear,Rocko,2,#c1),2)

  • First, evalutes $+(%,swear,Rocko,2,#c1) to %swearRocko2#c1
  • Second, evaluates %swearRocko2#c1 to 5, which is for example the value of the variable.

    But wait a second, why couldn't I just do level 1 evaluation for $+(%,swear,Rocko,2,#c1)?

    Well, like I noted in the "Notes" section, normal evaluation is of level 1, so putting $eval($+(%,swear,Rocko,2,#c1),1) would also return %swearRocko2#c1.
    Since we want to know the value of %swearRocko2#c1, we must enforce a level further, which is level 2.

    Important Note: in mIRC $eval(input,level) is the same as $(input,level) but shorter. I will use this shorter representation in the example.

    To conclude this example, we'll use a very very basic on text event that will show us the usage of $eval throughout.
    Do not worry if you do not know what a hash table is or how it works, we simply want to demonstrate the use of $eval.
    We will assume that we have a list of badwords in a hash table like the following:

    
    *badword1*
    *anotherbadword*
    *badword2*
    ...
    
    
    ON @*:TEXT:$($hfind(badwords,$strip($1-),1,W)):#:{
    
      VAR %offend = $+(%,swear,$cid,$chan,$nick) 
      INC $(%offend,1) 
      VAR %value = $(%offend,2) 
    
      IF (%value == 1) {
        msg # $nick this is your first warning! Do not swear.
      } 
      ELSEIF (%value == 2) {
        msg # $nick this is your second and final warning. 
      } 
      ELSE {
        msg # $nick This is your third offence which results in a ban. Goodbye.
        ban -k # $nick 2 Banned for swearing.
        UNSET $(%offend,1)
      } 
    }

    Ok this looks complicated, we'll have to go through this step by step:

    1. $($hfind(badwords,$strip($1-),1,W))
      There is a special usage of the short representation of $eval, being $(...) It can be used in matchtext of an event, to let the matchtext evaluate before matching. In our case it returns the value of $hfind, which is an item like *badword*, in case it matched the original text $1-. It is outside the scope of the tutorial to explain why exactly this works, and how $hfind works, or what hash tables are. Let's focus on $eval instead.
    2. VAR %offend = $+(%,swear,$cid,$chan,$nick)
      $+(%,swear,$cid,$chan,$nick) evaluates to something like: %swear2#c1Rocko
      We put %swear2#c1Rocko in the variable %offend.
    3. INC $(%offend,1)
      Why did we not just do inc %offend? Because that would have increased the value of %offend with 1. However we do not want to increase %offend with 1, but %swear2#c1Rocko with 1. Therefore we issue evaluation of level 1 on %offend, so that it evalutes to %swear2#c1Rocko. Now I know you'll start scratching your head: "Didn't you say that evaluation of level 1 is the same as the default evaluation, so why would I ever need to put a $(input,1) eval construct?" Ha! That's because of a specific mIRC behaviour with variables. When setting a variable, the variable is not evaluted. //var %a = 5 Lucky for us, the %a did not evaluate, or we wouldn't be able to set the variable %a in the first place. So I repeat, when setting a variable, the variable does not evaluate.

      Let's go back to our example: why not //inc %offend ? Well, %offend isn't evaluated because of the behaviour i just explained. So the normal default evaluation of mIRC to level 1 does not count here. Therefore we force mIRC to evaluate %offend, by using $(%offend,1), which evaluates to %swear2#c1Rocko before performing the //inc, so that it is %swear2#c1Rocko which gets an increased value, and not %offend.

      Why did I use level 1 and not level 2 evaluation? Simple, level 2 would have done this: %offend -> %swear2#c1Rocko -> 5 It would have resulted into something like this: //inc 5, which is impossible, we cannot inc a string that is not a variable.

    4. VAR %value = $(%offend,2)
      First level of evaluation: %offend -> %swear2#c1Rocko
      Second level of evaluation: %swear2#c1Rocko -> number, for example: 2
    5. IF (%value == 1) { .. }
      ELSEIF (%value == 2) { .. }
      ELSE { }
      We use the temporary variable %value, which holds the value of our dynamic variable %swear2#c1Rocko, to see what action we should take. The higher the number, the more offenses the person commited.
    6. UNSET $(%offend,1)
      Why did we not do "UNSET %offend". Well, %offend in our code is a local variable, which will be automatically destroyed. Even if it didn't, it's not %offend that we wish to unset, it is %swear2#c1Rocko. We want to unset it, because Rocko is banned from our channel on this specific network, so we don't need the variable anymore.

      Therefore, we force evaluation of %offend to %swear2#c1Rocko first, before using unset, so that it unsets %swear2#c1Rocko and not %offend.

    Note that you should not use the swearkicker example as it is here, as you do not have a hash table called "badwords" with badwords in it, so it will never match. The example is meant to be a framework to show usages of $eval, and can be used as a real practical example by creating a hash table "badwords" with wildcarded hash table items like *badword*.


  • 2. Conclusion  Back to Top

    You have first been presented with an abstract example which shows how $eval let's you evaluate an input string to a certain level. After seeing this theoretical example, I have presented you with a practical example in the form of a Swear Kicker. Although the tutorial was quite extensive, note that as you advance in scripting, you will find out usages of $eval which you didn't think of before. This is for example the case when dealing with commands like /timer or /scon|scid, where evaluation takes place twice. Nonetheless, with the information given, you should have a nice head start on others who've only read about $eval in the mIRC help file.