I have 2 classes: one with 2 properties and one with an array. I want to make an array of objects of the first class.
The example compiles, but gives a wrong answer. Why?
[indent=4]
class data
prop first_name : string = " "
prop last_name : string = " "
class Arr : Object
person : data
dataset : array of data[]
init
person = new data()
dataset = new array of data[3]
def date_input()
print "\n data input \n"
person.first_name = "Egon"
person.last_name = "Meier"
dataset[0] = person
print dataset[0].first_name + " " + dataset[0].last_name
person.first_name = "John"
person.last_name = "Schneider"
dataset[1] = person
print dataset[1].first_name + " " + dataset[1].last_name
person.first_name = "Erwin"
person.last_name = "Müller"
dataset[2] = person
print dataset[2].first_name + " " + dataset[2].last_name
def date_output()
print "\n data output \n"
for i : int = 0 to 2
print dataset[i].first_name + " " + dataset[i].last_name
init
Intl.setlocale()
var a = new Arr()
a.date_input()
a.date_output()
The fundamental problem is you are referring to the same person three times, but changing their name each time. In Genie there are both value types and reference types. Value types are simpler and automatically copied on assignment. For example:
A reference type has the advantage that it can be easily copied, Genie simply keeps a count of the references made. So to copy a reference type the reference count is increased by one, but this means that changes to the underlying object will affect all variables that refer to it:
In the working example below I have made
Persona value object by usingreadonlyproperties:Some details about the code:
readonlyan error will be given when you compile the program if it tries to change a detail ofPerson. In your example, if you change the properties ofdatato bereadonlythen the Vala compiler will warn you are trying to re-write the current objectPersonhas its data values set in the constructor and then any attempt after that to change them is an errorPersonthe propertyfirst_namehas the backing field_first_nameand it is that field that is set in the constructoradd_person()is used that takes aPersonas a parameter. This separates the concrete data from the abstract classadd_person()method to make sure the array doesn't go beyond its limits. If more people are added to the group than are allowed then an exception is raisedadd_person()calls in theinitblock create thePersonas part of the method call. This means a reference to aPersonobject is not kept in theinitblock