Boost logo

Boost :

From: Jeremy Pack (rostovpack_at_[hidden])
Date: 2007-06-07 17:14:49


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_at_[hidden]> 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
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk