Can anyone tell me why my class array has 10 items all identical to customer(10)?
dim TempCust as new classCustomer
dim i as integer
for i = 0 to 9
TempCust.name = “ABC” + i.totext
TempCust.Rate = i*101 + 0.357
TempCust.Active = true
Customers(i) = TempCust
next
I dimensioned the array in the declaration to be 10 elements (Customers(9))
Alternatively, I dimensioned it to (-1) and then I put this in the loop
Customers(i).append( TempCust)
And got same result.
I also checked it in the debugger, and every append, caused every element to update to the latest one, so the debugger progression of customers was like
0
then 1, 1
then 2, 2, 2
then 3, 3, 3, 3
etc.
I have spent an hour looking at the programming guide, the forum, and sample projects, and can not get this simple thing to work.
You’ve only created one instance of your class and assigned it to your array ten times. Move the Dim statement into the loop instead so a new instance is created before it’s assigned.
dim i as integer
for i = 0 to 9
dim TempCust as new classCustomer // this creates a new object each time
TempCust.name = "ABC" + i.totext
TempCust.Rate = i*101 + 0.357
TempCust.Active = true
Customers(i) = TempCust
next
Ok thank you. I would have expected this to be an error - because it looks like you are dimensioning the same thing over and over again. For example, this would not fly :
dim i as integer
dim i as integer
dim i as integer
so this line : " Customers(i) = TempCust "
is apparently different than “j = i” which send the value of i to j, but there are two different memory locations for i and j.
So does “Customers(i) = TempCust” seems more equivalent to equating the two items as clones with the same memory location, is that right?
Xojo respects scope so a variable dim’d within a method is only valid within that method, and one dim’d within a block (if, while, do, etc.) is only valid within that block.
“Clones” is the wrong term as it implies more than one object, but I think you’re on the right track. Internally, every variable holds an address to some thing, whether than thing is a string or an object, so assigning the value of var1 to var2 is setting up two variables that both hold the same address, i.e., there is still just one thing. For objects, you have to call “New” each time you want another one.
BTW, in the future, please use the Code tags to format your code and help us help you.
What do you mean by “Code tags”? I don’t understand what that means.
I expected an array of class objects would be something like this
For i = 0 to n
Customers(i) = new CustomerClass
Next
or else if n are already defined, then to append another one :
redim (Customers (Ubound)) as new CustomerClass
The main thing I am looking for is a single good example of how to make an array of class objects, where the number of array elements might vary. From looking at the documentation and example projects, I have not been able to find that.
PS - when I come back to these forum threads, it says I don’t have permission to give a response - so I have to copy my response, reload the page, then paste it and it works.
If you look at the toolbar as you type the message, there are a number of icons. One is labelled “Code” when you point at it and it will insert for you tags that will mark the text as code. For an example of what that looks like, see Tim’s post above.
Here is some example code:
dim custArr() as CustomerClass
for index as integer = 0 to someArbitraryLimit
dim c as new CustomerClass
c.Prop1 = value1
c.Prop2 = value2
// etc.
custArr.Append c
next
On every iteration of the loop, this creates a new CustomerClass instance, fills in its properties, then appends it to the array.
[quote=397667:@Gregory Moore]I expected an array of class objects would be something like this
For i = 0 to n
Customers(i) = new CustomerClass
Next
[/quote]
You are correct. Your original code just wasn’t doing this. It’s a very common mistake. There is a subtle difference between
dim c as CustomerClass
c = new CustomerClass
for i = 0 to n
Customers(i) = c
next
and
dim c as CustomerClass
for i = 0 to n
c = New CustomerClass
Customers(i) = c
next
The first will create a single instance of CustomerClass and append it to all the elements of the Customers array. The second creates a new instance of CustomerClass for each element of the Customers array.
As for Dim, that’s a matter of Scope. If you Dim a variable inside a block of code (IF, WHILE, FOR all define a block) then it exists only within that block. Ie.,
for i = 0 to n
dim c as CustomerClass // c is created anew each time
c = new CustomerClass
...
next // c is destroyed here
// c doesn't exist here
I personally prefer to dim the variable outside the block and only use NEW within the block
dim c as CustomerClass
for i = 0 to n
c = new CustomerClass
...
next
I never realized that Xojo was sensitive to Begin-End blocks. I assumed anything defined in a method was existent and available from the declaration until the end of the method. So thats a revelation, and contrary my prior programming experience.
But if you define an array of class objects outside in a module (as a global)
Customers(-1) as CustomerClass
Then, later within a method, you redim it or append it (which way is preferable?) ? And then I assume it makes that global with the new size?
In the example you cited, “I assume it makes that global with the new size” sounds like you think you’re dealing with different things. You’re not, there is only one array no matter how many ways you refer to it.
Example:
Module1
Global Arr() As String
Sub SomeMethod()
Arr.Append "A"
dim arr2() as string = Arr // Still just one array
redim arr2( 9 )
arr2( 9 ) = "B"
MsgBox Arr( 9 ) // "B"
End Sub
As for whether to use Redim or Append, it depends entirely on what you’re doing. If you know how many elements you need, you can use either. If you don’t, you must use Append. But do not under any circumstances Redim within a loop unless you despise your users.
[quote=397939:@Gregory Moore]But if you define an array of class objects outside in a module (as a global)
Customers(-1) as CustomerClass
Then, later within a method, you redim it or append it (which way is preferable?) ? And then I assume it makes that global with the new size?[/quote]
Correct.[quote=397939:@Gregory Moore]which way is preferable?[/quote]
If you know the number of elements you need, and if that number is sufficiently large, you get a little better performance out of a single Redim, followed by a loop that sets the values. Otherwise, use Append.
Hmm, interesting. I’ve always added a “Clone” method that copied the members of the class to a new instance of the class each time through the loop based on arrays of classes discussions from back in the RB 4 days on the NUG.
ReDim MyExamples(-1)
For x = 0 To NumExamplesNeeded
Dim thisExample As New Example
ThisExample.Member = value
...
MyExamples.Append thisExample.Clone
Next
The Clone method then creates a new instance of the class that is returned as a new instance and appended to the global (in my case) array of the class.
If I’m reading this correctly, the assignment of the inner loop copy of the temporary class is assigned to the permanent real copy retains that temporary copy to the permanent array with that mechanism. And, even though the inner loop data has gone out of scope, the now appended address of the temporary class to the permanent class sticks around because of the assignment.
While more of a curiosity, does anyone who was around back then remember WHY we discussed this beyond scope rules and came up with the Clone process? I used to have the NUG archived locally, but finally cleared the space last year.
[quote=416728:@Tim Jones]ReDim MyExamples(-1)
For x = 0 To NumExamplesNeeded
Dim thisExample As New Example
ThisExample.Member = value
…
MyExamples.Append thisExample.Clone
Next[/quote]
This seems like redundant code (unless I’m missing something). Presumably your clone method creates a new instance of my MyExample? Therefore you create a new MyExample and then clone it. I think you could get by with just the New and be done with it and add it to the array.
That was my point. Luckily, I only use this type of code-overkill at array initialization, so the overhead is not noticeable. However, it will be “not there” by the end of the day