VBScript subroutines and functions allow you to execute the code inside them at later times, such as when the bot fires an event.
Subroutines and functions can be collectively be called "methods" or just "functions".
You can and should use subroutines or
Subs to organize code into a block that will occur when the routine is called.
A subroutine starts with a
Sub keyword, followed by the name (must be a valid identifier), followed by a comma-separated list of parameters in parentheses (0 parameters is valid too). It ends with
End Sub. Example:
Sub NewSubroutine() ' Place code here End Sub
Put code between the two lines above, and when the subroutine is called, the code will be executed in order until the
End Sub line.
You should indent your code for readability based on the starting and ending of functions.
When writing a subroutine, you can put parameters that you want passed in the parentheses. The names of the variables you write in the subroutine's first line must be identifiers that define variables you can use throughout the subroutine.
Sub MySubroutine(Param1, Param2) AddChat vbGreen, "Parameter 1's value: " & Param1 AddChat vbGreen, "Parameter 2's value: " & Param2 End Sub
The first line of the subroutine is called its "signature".
StealthBot will call certain subroutines called script events, automatically (the list is on that page).
Otherwise, to call a custom-made subroutine, there are two ways:
There are weird variations, but generally, you can use the
Call keyword and you must have parentheses around the arguments; or you can omit the
Call keyword and you cannot have the parentheses.
When calling a subroutine, you must match the number of parameters with the number of arguments you pass.
Sub NewSubroutine(Argument1, Argument2, Argument3) AddQ "Argument 1: " & Argument1 AddQ "Argument 2: " & Argument2 AddQ "Argument 3: " & Argument3 End Sub
This example is a subroutine requiring three arguments. Call it either way:
Call NewSubroutine("arg 1", "hi", 2009)
NewSubroutine "arg 1", "hi", 2009
This example will call the subroutine with the three arguments (any other number of arguments will result in an error).
Subroutines cannot return a value, but a
Function can. A function has all of the same features as a subroutine, but the keyword
Sub is replaced by
Function MyFunction(Argument1, Argument2) MyFunction = Argument1 + Argument2 End Function
The above code makes a function that returns a value. The result of
Argument1 + Argument2 is stored into the function's name, where the function's name functions as a variable. When the function exits, whatever was stored into the function's variable is returned as a result.
Calling and return value
To call a function, you can call it like a subroutine, but then the result value will be ignored. To get the value of the result, you can either store it in a variable or pass it on to another subroutine or function.
VarResult = MyFunction(1, 1)
VarResult will now hold 2.
AddQ MyFunction(100, 200)
This code will pass the result (300) to the channel. Yes, we have been using AddQ, a more complex function which ultimately prints the first argument to the channel (AddQ has optional arguments, but VBScript functions cannot use the
Subroutines and functions cannot be put inside other subroutines or functions, but any of the other control blocks can go inside or outside of subroutines and functions.
Code outside of subroutines and functions are in the "global" scope as mentioned before, and code inside are in the "local" scope. Variables declared (or used only there) are destroyed when the sub "exits", or completes execution. This includes subroutine or function parameters.
The other way to have execution immediately leave the subroutine or function is to use an
Sub MySub() Exit Sub Call DoSomething() End Sub
In this example,
DoSomething will never be called by
MySub. It is more useful to use
Exit with a conditional block such as
If. In a function you would use
Exit Function instead.
Subroutines and functions can use the
Private keyword to declare privacy. A
Public function can be accessed by the defining script and any other script using the Scripts object. A
Private function can only be called by the defining script. Subroutines and functions without a privacy keyword are considered public, so the
Public keyword is often left out.
Private Sub PrivateToOtherScripts() '... End Sub
In a certain sense, the VBScript engine allows you to "override" methods by giving a method the same name as another in the same scope. On load, the engine will go through and load each line into memory. Later when a method is called, the last method of the specified name is executed, no matter parameter count (unlike in other programming languages).
If there is a Script Support Class method with the same name as a method in a module, calling that method will execute the module's method, not the SSC's method, unless you use the
SSC. prefix to specify that you are referring to the one in the Script Support Class. The module-level functions loaded into all scripts take advantage of this. To refer to the SSC function that each overrides (except IsEnabled calls GetSettingsEntry instead), use
SSC.FunctionName. All of them require you to provide the script's name as the last argument, though.
This can be used to your advantage for debugging purposes by "overriding" a function using Ribose's BlockExec script during run-time and seeing when the method is being called, for example.
' for BlockExec use only Function AddQ(Message) Dbg "ADDQ " & Message AddQ = 0 End Function
Note that you must match argument count for the function you want to override like that, or else when the method is called, "Wrong number of argument" errors will occur. Since VBScript doesn't support Optional or ParamArray parameters, you must know how many arguments your script is passing to such an SSC function in order to debug more effectively. The function you override doesn't have to be in the SSC; you could override a VBScript function in the same script.
You cannot do something similar to variables (a second
Dim of the same variable throws an error, but is unnecessary anyway since variables are all type Variant) or classes (a second
Class will throw an error, but it might be for the better good...).