Closed dasloop closed 8 years ago
So this is to make Ponder dynamic? E.g. in Python:
class Person:
def __init__(self, name):
self.name = name
self.age = 0
metacls = Person
john = metacls("John")
john.salary = 0.0 # 1) per instance
def PersonFactory(name, salary=0.0):
p = Person(name)
p.salary = salary # 2) add to all instances
return p
john2 = PersonFactory("John")
In a dynamic language this is pretty easy as the instances and meta-classes can be manipulated at runtime. In the first example above we add salary "per instance". Second example and if we use a factory to create all of the instances we can manipulate them before returning them.
This is not the same in C++/Ponder as we are exposing concrete classes, all under the same template (Person
). The values are contained in the class instance (i.e. a new
d instance of the class). Where would the extension property value be stored?
To add arbitrary data we could do something like use a dictionary of variants? This would be pretty inefficient in C++ but pretty much what Python is doing when you instance a class, or use a dictionary. E.g. std::map<std::string, variant>
So is what you want a variant dictionary?
In some applications both things are required (reflection and runtime extension). For example for a GIS application.
The extensibility can be provided by an external lib, using something a bit more sophisticated than a variant map. In any case the idea is that, you are correct.
I will request then two changes: 1) Add attributes at any time after setting up the Ponder Class (and not only when calling ponder::Class::declare for the first time) 2) For external attributes (can be even functions) call a external function with enough context (object, attribute id for gets, objects attribute id and variant for set).
Maybe 2 is better than include all the code in Ponder.
Currently Ponder is a reflection library, which is different from making C++ dynamic (like Python). C# has reflection but is also not dynamic, you cannot add extra members to classes at runtime. If you want a dynamic language then you may be better off using Python or Lua. If you have C++ code you could expose to the dynamic language so they can talk to each other.
It's not that it isn't impossible to do but I don't really have a need for this functionality. I have other work. You are welcome to get latest, branch the code, alter it, and submit a pull request. Then we can discuss what you have done and if/how it will make it into Ponder.
I will try then but, can you make a favour, can you implement the first request or let me know how to do it? To add attributes later on to an already defined class. Something like:
void declare() // register details (once)
{
ponder::Class::declare<Person>("Person")
.constructor<std::string>()
.property("name", &Person::name)
.function("speak", &Person::speak)
;
}
void declareAfterSomethingElse()
{
const ponder::Class& metaclass = ponder::classByName("Person");
metaclass.property("age", &Person::age, &Person::setAge);
}
Hi,
How difficult will be to add to ponder the possibility to expand objects with new attributes in runtime? For example: