VBScript Passing Parameters
Windows only

Overview

In VBScript, there are two ways values can be passed: ByVal and ByRef. Using ByVal, we can pass arguments as values whereas with the use of ByRef, we can pass arguments are references. This is the obvious bit, but, how do these two differ in practice?

Passing By Value

Consider the following code snippet:

Function GetValue(ByVal var)
  var = var + 1
End Function

Dim x: x = 5

'Pass the variable x to the GetValue function ByVal
Call GetValue(x)

Call Rhino.Print("x = " & CStr(x))

When you run the block of code above, you will get the following output:

x = 5

In other words, when we passed the variable x (ByVal) to the function GetValue, we were simply passing a copy of the variable x. When GetValue executes, var stores a copy of the variable x and increments itself by 1. Therefore, because what we are passing to GetValue is a copy of x, it cannot be modified.

Passing By Reference

Now, let’s look at another way of passing variables: By Reference.

Consider the following code snippet:

Function GetReference(ByRef var)
  var = var + 1
End Function

Dim x: x = 5

'Pass the variable x to the GetReference function ByRef
Call GetReference(x)

Call Rhino.Print("x = " & CStr(x))

When you run the block of code above, you will get the following output:

x = 6

Variable x was increment by 1. But why was x incremented? Only var must have incremented by 1, and not x? Well, that is the core concept behind passing variables by reference.

When the function GetReference executes, var becomes a reference of x, and therefore, any changes made to var would impact x. So if var increments itself by 1, so would x. If var becomes 0 (zero), so would x.

Let’s look at another example:

Function GetReference(ByRef arrArray)
  ReDim Preserve arrArray(UBound(arrArray)+1)
  arrArray(UBound(arrArray)) = 2
End Function

Dim newArray: newArray = Array(0, 1)
Call GetReference(newArray)

Will the size of newArray increase? Look at:

' new size: 2
Call Rhino.Print(UBound(newArray))

' new elements: 0, 1, 2
For x = LBound(newArray) To UBound(newArray)
  Call Rhino.Print(newArray(x))
Next

Since newArray was passed as a reference to the GetReference function, the change made to arrArray was reflected upon newArray as well. Thus, sizes of both arrays incremented by 1.

Is there a way to pass variables ByRef and still avoid this? Yes, there is. The answer lies in passing temporary variables…

ByRef & Temporary Variables

The advantage of using this approach is that you can pass temporary variables to n number of functions accepting arguments as reference, without having the base (original) variables modified. This is a good (and recommended) approach, since your original variables stay intact and you do not lose track of them when working with extensive function libraries. Please see a simple demonstration of this approach below:

Function GetReference(ByRef var)
  var = var + 1
End Function

Dim x: x = 5
Dim y: y = x

Call GetReference(y)

' Returns 5 (x remains unchanged)
Call Rhino.Print(x)
' Returns 6   
Call Rhino.Print(y)

Above, you will notice that as y became a temporary variable and was passed to GetReference, only it was modified. The variable x was unchanged. Thus, it’s recommended to use temporary variables when passing variables as reference.

Summary

Here is a summary:

  • (ByVal) Arguments do not change when passed by value.
  • (ByRef) If the function parameter is modified, it will have the same impact on the parameter that was passed by reference.
  • (ByRef) Because the passed parameters can be changed, we can pass multiple values from functions.
  • (ByRef) In a large function library, it can be hard to tell where the value was changed and what function the variable was supposed to perform.

Related Topics