Byref and ByVal part II

Long ago I wrote about byref & byval
Apparently this wasnt widely read not even by some long standing members of the community as I still see completely wrong explanations of bevel & byref persist.

First you have to understand that there are two types of VARIABLES.
VALUE types and REFERENCE types.
With a VALUE type the compiler sees there is space in memory set aside when your program runs to hold a value – a number a floating point value etc. The thing IN that spot IS the actual data.
With a REFERENCE type whats in that spot isnt the data directly – it s the address of the data.

Normally when you pass a value you pass it BYVAL
This is the default

So what exactly does this mean ?

I literally means that the value that is held by whatever type of variable is passed in can’t be altered.
If you pass in an integer, IN the method you can change it however you want, but those changes WILL NOT be preserved in the calling code.

Something like

Sub Opening
  dim I as integer = 100

  system.debuglog str(i) // prints 100

  foo(i)

  system.debuglog str(i) // prints 100
end sub

sub foo ( I as integer )
  I = 500
  system.debuglog "in foo " + str(i) // prints in foo 500
end sub

Would print 100 and 500 as indicated. The value would not be preserved from the call to foo. So when we return the next time I is printed in the caller it prints 100.

This is the easy case for a VALUE type.

If we switch to a REFERENCE type its EXACTLY THE SAME ! The trick is “the value” that is preserved is the pointer, or reference, that is preserved. NOT THE data referred to. Let me illustrate

Sub Opening
  Dim d As New date
  System.debuglog d.SQLDateTime
  foo(d)
  System.debuglog d.SQLDateTime

End Sub

sub foo ( d as date )
  
  d = New date(d.year - 2, d.month - 4, d.day - 6, _
    d.hour - 8, d.minute - 10)

  System.debuglog "in foo = " + d.SQLDateTime
end sub

Note that if you run this you will see that d in the main calling routine before & after the call prints the SAME date. This despite the fact that in the called routine, foo, we altered the date that d referred to.
What this shows is that what is being passed by VALUE is the REFERENCE (pointer or address)

And again IN the routine we called we can do whatever we want to change what the REFERENCE is by creating a new one and that change wont stick when we leave.

  • there IS a thing that many people referen to as “byref” that ISNT
    SEE THE END OF THIS ARTICLE

No wit we switch to using BYREF to make it so “changes to the value held” are preserved we get

Sub Opening
  dim I as integer = 100

  system.debuglog str(i) // prints 100

  foo(i)

  system.debuglog str(i) // prints 500 !!!!!!!!!!!!
end sub

sub foo ( byref I as integer )
  I = 500
  system.debuglog "in foo " + str(i) // prints in foo 500
end sub

The change to the value held IS preserved !
BYREF allows us to alter what the variable held

And for BYREF with a reference type its much the same

Sub Opening
  Dim d As New date
  System.debuglog d.SQLDateTime
  foo(d)
  System.debuglog d.SQLDateTime // prints THE SAME as from foo !!!!

End Sub

sub foo ( byref d as date )
  
  d = New date(d.year - 2, d.month - 4, d.day - 6, _
    d.hour - 8, d.minute - 10)

  System.debuglog "in foo = " + d.SQLDateTime
end sub

BYREF lets you change what the VALUE of the passed in variable is.
But, it depends on what kind of value is passed in to see what the effects are

SOME people incorrectly refer to the following as “byref”

Sub Opening
  Dim d As New date
  System.debuglog d.SQLDateTime
  foo(d)
  System.debuglog d.SQLDateTime // prints THE SAME as from foo !!!!

End Sub

sub foo ( d as date )
  
  d.hour = d.hour - 12

  System.debuglog "in foo = " + d.SQLDateTime
end sub

Bu this is NOT “byref”
We haven’t change the REFERENCE ( the actual instance) being referred to

We HAVE altered one of the properties of the item passed in – that happens to be a reference type

I hope this clears up the confusion