
We're actually planning on writing an example "C++ interpreter", partially just for debugging reflected classes. I'd actually want to separate the "reflection" of the methods from the declaration of the class - the same as Boost.Extension does not require any plugin declarations in the class header file. So if we had the following class: class Car { private: // whatever private stuff public: bool start(); bool turn(float angle); }; Then we could reflect it as: boost::extension::reflection car_reflection<Car, std::string>("A Car!"); /* Here we declare that we are reflecting out a Car. The second template parameter declares that we will describe this reflection using a string. Any arbitrary type could be used here. */ car_reflection.add<int>(&Car::start, 3); car_reflection.add<std::string, std::string>(&Car::turn, "turn", "turn_angle"); /* Here we add two methods to the reflection. The library must correctly parse and remember the parameters and return type of these methods. Here, we elect to describe the first method using a number and the second using a string. For the second method, the library knows now that it is a function of Car called turn that takes a float named "turn_angle". */ This allows us to choose exactly which methods are reflected. The techniques I used above are very similar to the methods used for declaring plugins in Boost.Extension, and should be clear to those who have examined those. Now you can export it using the Boost.Extension methods as usual. You'd use the car_reflection variable as the Info parameter, and export a factory for a generic reflected_object. Then you could create the reflected_object, initializing it with a reference to the reflected_car object, and then begin using it in whatever module you're in. Now, the real trick is how we will then call those methods. There are a number of possible ways of doing this. I think we'll implement a number of different methods and let the community decide which ones are the most useful. I'd imagine we'd want about three different ways of accessing these reflected methods: 1 - Call functions when you know the exact identifier (whatever type you decided the identifier should be ...), parameters, and return value. 2 - Call functions when you just put a whole bunch of possible parameters into a map, and then the call succeeds if it can find the values it needs, for instance: parameter_map.add<float, std::string>(.5f, "turn_value"); // A parameter named // red_value (we're describing it with a string), // which is a float with a value of .5f my_reflected_car->call<std::string>("turn", parameter_map); // Now we call the turn // function, which looks for the values it needs // in the parameter_map. If it finds them, the call // succeeds, and a value is returned (boost::any probably). Anyway, the above are just my thoughts about how I'd like to see the interface. Since Mariano is writing it, he'll have to decide. Jeremy On 6/7/07, Janek Kozicki <janek_listy@wp.pl> wrote:
Jeremy Pack said: (by the date of Wed, 6 Jun 2007 11:25:20 -0700)
7. can you explain shortly what Reflection is? Or some URL with explanation, please.
I think of reflection as runtime type information about the methods of a class for which you do not have access to any of its base classes. As such, there are a lot of directions one could go with it - I'm not sure which direction Mariano will choose. Some of these directions are really hard in C++. I think we'll be discussing that a lot in about three weeks - and will want lots of input from the community.
I see... Some time ago I've been thinking about similar thing also: I wanted to create some Scriptable interface. The C++ coder will register methods in his class using some macros. And later those methods could be called by some kind of interpreter reading from std::cin.
Eg. you could register method 'int Foo(int)', and later when the interpreter reads from std::cin a string "Foo(42)" it would parse the input and call this method with appropriate argument, then print the return value.
I see where the word 'reflection' comes from - the methods of a class are reflected in some runtime information.
I abadoned this project, but the only way that I could see is to use macros - one macro per method. Which effectively doubles the length of *.hpp file with class definition.
Maybe it is possible to write some really magic macro, which would allow to declare a method in the class and register it in the same line:
class Bar { MAGIC(int Foo(int);) };
that isn't going to work ;) what to do with brackets, etc? What's with that semicolon? ;-)
-- Janek Kozicki | _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost