Possible bug with arrays + generic funcs (solved)
Monkey Forums/Monkey Programming/Possible bug with arrays + generic funcs (solved)
| ||
It might be that I don't completely understand how arrays behave but I assume that the following code:Function Main:Int() Local a:Int[] = [1, 2, 3] Local b:Int[] = [5, 5, 5, 5] Generic<Int>.Merge(a, b) Print a.Length Return 0 End Class Generic<T> Function Merge:Void(array1:T[], array2:T[]) Local offset:Int = array1.Length array1 = array1.Resize(array1.Length + array2.Length) For Local i:Int = 0 Until array2.Length array1[i+offset] = array2[i] Next Print array1.Length End End should output 7 twice, but instead I get 7 (inside the Merge function) and then 3 (the original array size). I thought arrays are passed by reference? |
| ||
array1 = array1.Resize(array1.Length + array2.Length) This creates a new (larger) instance of T[] with the contents of the original array1, and assigns it to the LOCAL array1 parameter. You're replacing the local reference with your new one, so the original is unchanged. Edit: Technically there are no "by reference" arguments in Monkey. True "byref" arguments would allow you to modify the value of the original variable you're passing in, not just the contents of the object. It's the same in Java and many other languages. C/C++/C# are good examples of byref, because you can actually use pointers (or the "ref" keyword in C#). It's mostly semantics, but the distinction is important. |
| ||
So true. A possible solution would be this:Function Main:Int() Local a:Int[] = [1, 2, 3] Local b:Int[] = [5, 5, 5, 5] a = Generic<Int>.Merge(a, b) Print a.Length Return 0 End Class Generic<T> Function Merge:T[](array1:T[], array2:T[]) Local offset:Int = array1.Length array1 = array1.Resize(array1.Length + array2.Length) For Local i:Int = 0 Until array2.Length array1[i+offset] = array2[i] Next Print array1.Length Return array1 End End but I am sure you knew that. array1 is just a local variable pointing to the location of the array. When you resize the array a new array is created and the location passed to the array1 variable. So the original location is removed from the array1 variable and the new location assigned to it. which implies that it no longer points to the original array. It works the same as with any other parameter in a method or function. |
| ||
Jesse's solution is correct. On a related note, you may want to look at Diddy's Arrays class, as it provides exactly the functionality you are after. It has no dependencies. http://code.google.com/p/diddy/source/browse/src/diddy/arrays.monkey |
| ||
Wow, thanks for explanation guys, it's very clear to me now. I completely missed that it becomes a local variable after resizing. |
| ||
Very common gotcha with arrays, because you *can* pass an array to a function that changes values in it - you just can't have a function that reallocates the array. |