I see a behavior that surprised me — and I honestly didn’t think it’s been working this way unless I’m going crazy. But maybe you can explain this to me. I have an array named Board which is 8x8.
Var tempBoard(7, 7) As String = board tempBoard(7,7) = “X” tempBoard(7,6) = “X” tempBoard(7,5) = “X” tempBoard(7,4) = “X”
This code is setting positions 7,7 through 7,4 in tempBoard to “X,” just like I expected.
But it’s also setting the values 7,7 through 7,4 in. Board to “X.” So I’m guessing that tempBoard and Board are sharing a memory location.
But why? Why wasn’t tempBoard initialized as an independent variable? I can work around it by running through a loop that copies the values from board to tempBoard. But I’d like to understand why it’s behaving like this.
In your declaration for the array, you are assigning it the value of board. An array is an object, and it obeys all the normal rules about references. The variables tempBoard and board point to the same array object in your code, so any modifications affect the same object.
In my opinion (not shared by everyone) Xojo Arrays are “weird” with some complicated behavior - in short, it’s not always obvious when a new array object is or is not created.
You may find this discussion interesting: Xojo WTF
A new array is created when you declare it, call the Array function, or call ToArray. I may have missed another method creating a new array but these would be the main ways.
Public Function Foobar(ParamArray x as Integer) As integer()
return x // in this function, x is a newly created array containing the parameters
End Function
var xx() as Integer = Foobar(1,2,3)
I’ve also assumed that if I pass an array as a parameter to a subroutine, I’m passing it by value and not by memory location. And if I change a member of the array in the routine, the change is not carried back to the calling routine.
in Xojo, the Array object itself is always passed by reference, so a function gets a pointer to the actual array, and any changes made in the function are visible on the original array outside the function.
You can also pass the Array parameter ByRef but this means something different: inside a function with a ByRef Array parameter, the function can change the actual reference itself.
Imagine this:
Public Sub foo(x() as integer)
x(0) = 99
x = nil // this has no effect outside the function
End Sub
var a() as integer = Array(1,2,3)
Call foobar(a) // now a() contains (99,1,3)
vs. using ByRef
Public Sub bar(ByRef x() as integer)
x = Array(7,8,9)
End Sub
var a() as integer = Array(1,2,3)
var b() as integer = a // b is a reference, pointing to a()
Call bar(b)
// at this point,
// a and b now point to different array objects
// a = (7,8,9)
// b = (1,2,3)
I think the documentation could be better, for example this section (link):
var names(2), copyNames(2) As String
names = Array("Fred", "Ginger", "Stanley")
copyNames = names
The last statement assigns the values of all three elements of names to the first three elements of copyNames. If copyNames had fewer elements than names, then additional elements would first be added to copyNames and the assignment of all the elements of names to copyNames would be completed.
To me this is unclear, and can be read to imply that the array values are copied, but that’s not what happens.
Between reading these replies and reading the thread that was linked to, I have no idea at all what to expect when I pass an array to a routine. It’s probably the terminology that gets me confused. I’ll just go test it for myself.
Xojo uses the LLVM compiler these days. It translates your Xojo down to an intermediate representation that is then compiled to bytecode by LLVM. (Note that the Android platform uses a completely different system)
This decision is one of the best they ever made - sitting on top of LLVM has allowed us to inherit all the benefits of ongoing LLVM development without Xojo having to roll it themselves. It is why we have XojoScript, for starters.
You are passing it by reference. One important aspect of the Xojo language is that it does not make copies of objects for you. Wherever you pass around an object, you are passing a reference to it. Xojo will not make a copy of an array, for example, whereas it will make a copy of an intrinsic like integer or color.
The documentation claims otherwise: “If copyNames had fewer elements than names, then additional elements would first be added to copyNames and the assignment of all the elements of names to copyNames would be completed.” There is no implication; the documentation explicitly states that all the elements get copied and the receiving array is redimensioned first to make sure they all fit.
That is a really unfortunate description in the documentation. It does go on to say that the 2 variables point to the same array in the next paragraph, but the section you quote is very misleading.