[solved] Method to instantiate classes from files

Hello

I created a class (call it “Tank”) with around 20 properties. One sub-class is forecast with some more properties. The user should have the choice of one among 5 instantiations of this class (say “Tank1”, “Bidon2”,…). Among the properties, some characterise the “Tank” (eg : volume, content, temperature), others will be computed.

I would like to store the characteristics of each “Tank” in a separate file, something like this :

Tank1.txt
volume = 10
content = water
temperature = 20

Bidon2.txt
volume = 100
content = oil
temperature = 30

This part is already working, as the one which reads the file and separate the lines in 2 variables : PropertyName, PropertyValue

Then, to initiate the “tank”, I thought looping until EOF and allocate the PropertyValue to the appropriate PropertyName, creating a method like this one :

Sub Allocation(TankType as Tank, PropertyName as string, PropertyValue as single)
me.PropertyName = PropertyValue
Return

As you guess, it does’nt work, as PropertyName is not a Tank property.

Your help will be much appreciated.

Patrice

P.S : you may answer in French, if you prefer, as it is my mother tongue

If you use that method, then the constructor could accept the whole text file as a parameter.
In the constructor, split the file into rows using Split() and endofline markers

Then you could do it using force:

untested, and incomplete…

[code]

dim fields() as string
dim row() as string
row = split(fileparameter,endofline)
for x as integer = 0 to rowcount
fields= split(row(x),"=")
if trim(fields(0)) = “volume” then m_volumeproperty = val(trim(fields(1)))
if trim(fields(0)) = “content” then m_contentproperty = trim(fields(1))
next[/code]

XML would probably be a better choice of format.

Thanks Jeff for your rapid answer, but…

I would like avoiding to hard code the name of the property. Up to now, only 3 properties need to be addressed, but I know that some more will be added during the project.
I did it already, creating a Tank.ini method and an array which buffered each PropertyValue. Something like that :

Tank.ini
Tank.Volume = Buffer(1)
Tank.Content = Buffer(2)
…

It works.

My intention is to simplify my life by :

  • adding (or deleting) properties to Tank
  • modifying the text files with a text editor (adding or deleting lines)
  • using the same method for the “SuperTank” class, “VerticalTank” class or whatever subclasses I will create

and that’s why I try to pass the name of the property as a variable. Maybe using MemoryBlock and pointer, but I am far far beyond my skills

Patrice

You could add a dictionary property to your Tank class to hold any arbitrary set of property name and property value pairs.

Look into Introspection, it will let you do exactly what you need.

Thanks Robert and Kem

I will try both suggestions and keep you inform. It will take some times as I am busy otherwise

Patrice

Hello

I tried both solutions, and I will use “Introspection”. Here it’s what I did as proof of concept :

Using dictionary

  • I created a new Property named CProp (Dictionary) for my class Tank
  • I instantiate the “Volume” like this : Tank1.Cprop.Value(“Volume”) = 75
  • and to check : Valvol.text = Tank1.Cprop.Value(“Volume”) (where Valvol is a TextField).

It’ works.

For me, the main drawback is that the code is bigger and less “readable”. Compare :
Tank1.Volume and Tank1.Cprop.Value(“Volume”) in a formula…

Using Introspection

I created a method [i]Allocation(TypeVol as Tank, s as string, valeur as single)

Dim MyAttributes() as Introspection.PropertyInfo
MyAttributes()=Introspection.GetType(TypeVol).GetProperties

For Each p As Introspection.PropertyInfo In MyAttributes

if p.Name = s then
p.value(TypeVol) = valeur
end if

next[/I]

When testing “'Introspection”, I noticed that

  • the properties where ranked by their order of creation, and not by alphabetical order
  • an index appeared as a new “variable”

This could be a problem if the order in the text file is not the same. That’s the reason why I test the name of the property against the string. At this stage of the program, speed is not an issue, as it is in the “Initialisation” part.

To check, I try this

Allocation(Tank1,“T”,286)
Allocation(Tank1,“Vol”,85)

Valvol.Text = str(Tank1.Vol)

And It work’s

By the way, I was looking for more information about “Introspection” in the forum and I found a post which exposed exactly the same problem, 2 years ago :

https://forum.xojo.com/32217-value-of-a-variable-named-in-a-string/0#p264030

No solution at that time. I will cross reference the posts

Thanks for your help

Patrice

First, be aware that there is a “code” tag here that make your posted code more readable than just italics.

For the Introspection code, I would not rely on order but on matching the name of the property to the key from the text file, which (I think) is what you’re trying to do. You can do that in two ways:

  • First create a Dictionary where the property name is the key and the PropertyInfo is the value. In this scenario, you would cycle through the text file keys and, where there is a match, use the PropertyInfo to store the value. You can keep that Dictionary around to load further text files.
  • Turn the text file into a Dictionary with key = value, then cycle through your class’ PropertyInfo and fill in the properties it can match by name.

Thanks for the advice and sorry for the italics.

Patrice

Just throwing this out there, but another option is XojoScript. You could set the context object as the class you’re building, then the script code has direct access to the object’s public methods and properties. You script would then look like just Xojo code to setup the properties:

volume = 100 content = 'oil' temperature = 30

Of course, you have to deal with potential compile errors due to typos, but it’s still an option.

Thanks Thom

I will keep this option in my “options/new ideas” list. For the moment, I’m teared apart between

  • exploring all XOJO possibilities in order to set good foundations for my program
  • continuing the program.

I think, I will continue to develop the program as XOJO is so rich that exploration is a never ending story… At the same time, I open this “options/new ideas” list for the time I’m tired with the main stream of development.

Nevertheless, I already know that I will explore scripting and XML for other purposes, so I’m quite sure that I will test your proposal later on.

Patrice

Writing out/into a dictionary using JSON might be a good thing (easier & faster than XML) unless it needs to be human readable too.

We use Kem Tekinay’s drop-in replacement - works a treat! https://forum.xojo.com/49940-update-to-jsonitem-mtc-now-with-m-json-module/0

Thanks Eric

I still don’t know JSON, so I don’t know what I can do with it. I will put it on my list :).

Nevertheless, up to now, the use of XML that I envisaged should be human readable, for QA, maintenance and updating purposes.