Why VBN Argument Passing is Different
The default method for passing arguments in VBN is different. When you entered the sample code in Listing 2 into the VBN environment, VBN automatically supplied the ByVal keyword in the argument list for SquareIt(). As you already know, ByVal means that the argument is the rvalue of n from the Form1_Load procedure, not the lvalue as is the case for the VB6 code in Listing 2. Although the actual mechanism is different, conceptually you can think of the rvalue for n in the Form1_Load procedure being placed in a CPU register and then the SquareIt() procedure is called. The important thing to notice is that SquareIt() receives a copy of n, not the lvalue where n is located in memory.
To confirm this, set a breakpoint on the final End Sub statement in Listing 2 and run the program. Place the cursor over val and observe that its value is 100, but the value of n in the Form1_Load procedure remains unchanged at 10. Clearly, the lvalue of n is not being used by the variable val in the SquareIt() procedure. This is not the behavior we saw using Listing 2.
Because SquareIt() receives a copy of n (i.e., its rvalue) and not its lvalue, there is no way that SquareIt() can alter the current value of n in the Form1_Load procedure. In other words, n is not visible outside the Form1_Load procedure. This means that the scope, or visibility, of n is limited to the Form1_Load procedure. Because the scope of n is confined to the Form1_Load procedure, only the code in that procedure can change n. By limiting the scope of n, it is less likely that other code in the program will inadvertently contaminate the value of n. This is a good thing.
The ability to limit the access to a data item is the primary idea behind encapsulation, a basic cornerstone of Object Oriented Programming (OOP). Encapsulation encourages you to not pass the lvalue of your data items around to other parts of a program unless it is absolutely necessary. The default behavior of VBN is to keep the lvalue limited to the procedure where the data item is defined. OOP doesn't mind passing rvalues around the program as needed, but takes a dim view of automatically letting a data item's lvalue be known to other parts of the program.
What if you really do need another procedure to have direct access to the lvalue of a data item? Simple. All you have to do is change the default ByVal keyword in the argument list to ByRef. If you make this change for the code shown in Listing 2, you will find that n is permanently changed by SquareIt(). This change makes the VBN version functionally equivalent to the VB6 version.