byref question

Sub Extract(byref cmd() as String, byref data() as String)
   ...
  return
End Sub

I trace into this method and both arrays are populated but the caller get nil, nil back…
?

How are you calling it?
How are you testing and assigning to cmd and data in the method?

and why are you passing them byref ?

Here is a ByRef call which seems to work on Windows:

[code]Pushbutton1.Action()
Dim MyArray(4) as Integer
MyArray(0) = 0
MyArray(1) = 1
MyArray(2) = 0
MyArray(3) = 0

AddSome(MyArray)
DIm i as Integer
Label1.Text = " "
For i = 0 to 3
Label1.Text = Label1.Text + “MyArray(” + Cstr(i) + ") = " +Cstr(MyArray(i)) + EndOfLine
Next i
End Sub[/code]

Sub AddSome(ByRef SomeInt() as Integer) SomeInt(2) = 2 SomeInt(3) = 3 End Sub

If the code works then the output should be:

[quote]MyArray(0) = 0
MyArray(1) = 1
MyArray(2) = 2
MyArray(3) = 3[/quote]

Unless you are trying to assign new arrays to the original variables, you don’t need ByRef. Arrays are like objects in that you pass a reference to them anyway. For example:

dim a() as integer
AddSome( a )

Sub AddSome (a() As Integer)
  a.Append 1
  a.Append 2
End Sub

This will work just fine. On the other hand:

dim a() as integer
AddSome( a )

Sub AddSome (a() As Integer)
  a = Array( 1, 2, 3 )
End Sub

This will leave the original a untouched because the method assigned a new array to its local variable. On the other hand, if a had been passed ByRef in this case, it would have ended up containing the new array.

ByRef is one of the harder things to understand in the language and usually involves an “ah HA” moment.

Norman:
I wanted to return more than one array from a function.
So I passed the two arrays byref.

Eugene:
I tried this on my mac and got
MyArray(0) = 0

Kem:
I’m not having an Ah ha moment more like an ahhh sh… moment… :slight_smile:
Are you saying I should remove the ByRef parameter from the function definition?

I’m saying it probably doesn’t do anything for you, but I’d have to see your code. If you want new arrays assigned to the local variables in the calling method, then you need ByRef. Otherwise, you just don’t.

The examples given work… It must be me…

Hi Brian,

Here is a ByRef program that works on Windows 8.1. Let me know if this works on your system.

ByRef Binary Project

If the example ByRef works on your Mac, then the output should be:

[quote]MyArray(0) = 0
MyArray(1) = 1
MyArray(2) = 2
MyArray(3) = 3[/quote]

If there is something wrong with processing ByRef’s on the computer then the output would be:

[quote]MyArray(0) = 0
MyArray(1) = 1
MyArray(2) = 0
MyArray(3) = 0[/quote]

[quote=187575:@Brian O’Brien]Norman:
I wanted to return more than one array from a function.
So I passed the two arrays byref.
[/quote]
No need to pass them byref

[quote=187633:@Eugene Dakin]Hi Brian,
Here is a ByRef program that works on Windows 8.1. Let me know if this works on your system.
ByRef Binary Project[/quote]
You will have the same result whether there is a ByRef statement or not, as arrays are pointers anyway. No matter how the parameter is defined in the method, you will always manipulate the array of the caller.

With byref you can outright replace one array with another
Without it you can only alter the contents of the array passed in
ie/

sub foo1(byref a() as string) a = array ( "a" , b", "c") end sub

behaves entirely different than

sub foo2(a() as string) a = array ( "a" , b", "c") end sub

If you have code like

[code] dim a() as string

foo1( a )[/code]

before the call a() might have an address of 123
After the call it will be some other address - you’ve literally replaced the original array
And the result assigned will be returned to the caller

If you have code like

[code] dim a() as string

foo2( a )[/code]

before the call a() might have an address of 123.
After the call it will be at the same address - you’ve only replaced the contents at best.
And the result, because of how we altered it IN foo2, is NOT returned to the caller.

Subtle but hugely important to know what BYREF actually does

That is clearly not possible. If Brian is encountering an error, it is because of something he is doing in his code, which he has not told us about.

Right. Eugene’s example does not demonstrate ByRef.

Here is an updated example demonstrating ByRef.

[quote=187668:@Norman Palardy]With byref you can outright replace one array with another
Without it you can only alter the contents of the array passed in[/quote]
Didn’t know that. Though it is somehow illogical that there is a difference between the following two:
With ByRef:

  • Reassigning an array with Array(“a”, “b”, “c”) replaces the array – ok
  • ReDim(-1) clears the array – ok
    Without ByRef:
  • Reassigning an array with Array(“a”, “b”, “c”) does not replace the array – ok
  • ReDim(-1) clears the array – ???
    Shouldn’t the latter not not clear the array?

Just realized that Shouldn’t the latter not not clear the array? is a three time negation (or whatever the English term for it is):
Should not the latter not not clear the array?

Maybe “clearing an array” is a kind of negation too? Then it would be a four time negation…

Yes, as it should. Arrays are treated similar to any other object. You can change the contents, but not replace it with another object. Redim changes the contents of the array, so its effect is the same whether you pass ByVal or ByRef. The subtle difference is that ByRef allows you to create an entirely new array and replace the one you were passed. You can see this in the example I posted, where after the call, you have 2 arrays, the original and a brand new one.

Ok, I see. ReDim is like Remove() until empty, while Array(…) is like calling New Object(). Makes sense.

Yes. Redim can also act like Append.

dim a(2) as integer
a(0) = 0
a(1) = 10
a(2) = 20
redim a(4)   // adds 2 more entries and leaves the existing ones intact
a(3) = 30
a(4) = 40
msgbox str(a(1))   // 10