Accessing class/attributes from string

Hi,

What I want to do using processing 3.x with java:
Basically read all variable values of a class, but accessing them indirectly by a string.

e.g.

class book {
 String title;
 int catalogue;
 String author;
}

...

books[0].title = "test";
books[0].catalogue = 100;
books[0].author = "alpha";
books[1].title = "more testing";
books[1].catalogue = 200;
books[1].author = "beta";
books[2].title = "even more testing";
books[2].catalogue = 300;
books[2].author = "gamma";

I would like to have a string list or similar where the entries are “title”,“catalogue”,“author”…
So, rather than:
savefiledata = books[0].title

something by way of:
savefiledata = books[0].<insert string value here>

The class I have created a lot more than 3 attributes, and I don’t want to have to manually keep track of them all when I add/change/delete them. It’s for a game where I’m trying to create a savegame file by reading all the classes/values etc etc

I’ve done a bit of searching and it seems that it may not be possible, I have tried using a hashmap but can’t quite figure out if it would be useful or not.

Please don’t tell me the only way is to do it manually haha

Thanks in advance for any replies

Cheers,
Keith

You’re better off using a Table for it: :bulb:

2 Likes

classes use records with variables by name,
and tables have column names BUT can also be called by number.

for me the name thing of classes was actually a disadvantage,
compared to the handling of [ ][ ]

i must admit that i did not get what you wanted to do with having a string for a named class record!

while @GoToLoop is absolutely right about the “save/load file” handling with using “table”
i play my idea about a better “array of class” handling,
take a look at:

// multi dim array are possible, but only of one type like: int[][]
// classes allow (named) records mix like: int float boolean objects 
// add has the advantage that it can have internal functions
// array of class, would be a single dim array of above records,
// combines that all, BUT
// it does not allow a easy ( numeric ) looping like a  [][]

// p.s. tables allow using column names ( word ) OR numbers 

// here my "get from class" idea:


class Book {
  String title;
  int catalogue;
  String author;

  //  Book() {}
  String get(int getit) {                        // readout like matrix
    if ( getit == 0 ) return title;
    if ( getit == 1 ) return str(catalogue);     // not INT
    if ( getit == 2 ) return author;
    return("NaN");
  }
}

int many = 3;
Book[] books = new Book[many];

void setup() {
  for ( int i =0; i< books.length; i++ )   books[i] = new Book();
  books[0].title = "T1";
  books[0].catalogue = 100;
  books[0].author = "alpha";
  books[1].title = "T2";
  books[1].catalogue = 200;
  books[1].author = "beta";
  books[2].title = "T3";
  books[2].catalogue = 300;
  books[2].author = "gamma";
  
  
  for ( int i = 0; i < books.length; i++ )
    for ( int l = 0; l < 3; l++ )
      println("i: "+i+" l: "+l+" : "+books[i].get(l));
}


1 Like

Do you mean look them up by value? Or do you mean iterate over all fields without naming them? If the second, Table has TableRow, and it will do just what you want – you can dump the whole table or the whole row without naming each of the fields.

If you have a custom class and are constantly adding fields to it, then just write a class method.

savefiledata = books[0].savedata();

Now when you add/change/delete your class attributes, update the class savedata() method (if they are attributes that you want to save). This keeps your interface to your field collection in one place, rather than scattered all over.

Another approach: say that your class potentially has hundreds of fields, and those fields are ad-hoc, or even user-generated per-object. You feel like you can’t possibly enumerate them all. You could manage them like this:

class book {
  String title;
  StringDict s;
  IntDict i;
}

Now you can search for if you book has a field, add a field, delete a field, or dump all the fields (whatever they are).

/**
 * Class fields in Dicts
 * 2019-08 Processing 3.4
 * discourse.processing.org/t/accessing-class-attributes-from-string/13583/2
 */

void setup() {
  Book mybook = new Book("mybook");
  mybook.i.set("catalogue", 200);
  mybook.i.set("foo", 700);
  mybook.f.set("bar", 9.95);
  mybook.s.set("baz", "qwerty");
  
  println("\nretrieve by name:");
  if (mybook.i.hasKey("catalogue")){
    println(mybook.i.get("catalogue"));
  }
  
  println("\nlist all fields:");
  mybook.printFields();
}

class Book {
  String title;
  FloatDict f;
  IntDict i;
  StringDict s;
  Book(String title){
    this.title = title;
    this.f = new FloatDict();
    this.i = new IntDict();
    this.s = new StringDict();
  }
  void printFields(){
    for (String key : this.f.keys()) {
      println(key, this.f.get(key));
    }
    for (String key : this.i.keys()) {
      println(key, this.i.get(key));
    }
    for (String key : this.s.keys()) {
      println(key, this.s.get(key));
    }
  }
  void saveData(){
    // list and iterate over fields here for saving
  }
}

If that doesn’t help, can you give a concrete example of what you are trying to do?

1 Like