Introspection/Reflection/etc on Linux

J Arrizza cppgent0 at gmail.com
Sun Oct 23 20:37:23 PDT 2011


Robert, I tried .stringof and it didn't quite get me as far as I wanted.

But the using a template got me much closer:

unittest
  {
  //create bob to kick off the whole thing
  new Bob();
  }

class Base
  {
    // find all the derived members and run them
    // Base doesn't have to know anything about the derived classes
    public void runallin(alias T) ()
    {
      void delegate() dg;

      //create a delegate and run it
      foreach (i, m; __traits(derivedMembers, T))
        {
        //skip ctor, no need to run it again.
        if (m != "__ctor")
          {
          writeln("== i=", i, "  m=", m);

          //by trial and error, I found I need to use
          //    5 + the number of methods in class Base (exclude ctor)
          //right now, no additional methods, so 5 it is.
          dg.funcptr = cast(void function()) this.classinfo.vtbl[i + 5];
          dg.ptr = cast(void*) this;
          writeln("   calling dg");
          dg();
          }
        }
    }
  }

// the class to auto-run
class Bob: Base
  {
  this()
    {
    runallin!Bob;
    }

  public void inBob1()
      {
        writeln("   in bob : inBob1()");
      }

  public void inBob2()
    {
      writeln("   in bob : inBob2()");
    }
  }


Here's the output:

== i=1  m=inBob1
   calling dg
   in bob : inBob1()
== i=2  m=inBob2
   calling dg
   in bob : inBob2()


Getting closer. Next:
- check the signature of the methods (I want to run void fn(void) only)
- find all the classes in a given module so I don't have to "new Bob()"

Thanks for everyone's help,
John


On Sun, Oct 23, 2011 at 9:21 AM, Robert Jacques <sandford at jhu.edu> wrote:

> On Sun, 23 Oct 2011 02:59:48 -0400, J Arrizza <cppgent0 at gmail.com> wrote:
>
>  The idea here was to create a base class. That base class would have a
>> function register() which took a function name or function pointer, and
>>
>> create a delegate at compile time. register() would add the delegate  and
>> the function name as a string into the hash. At runtime, I pass in the
>> string, get the delegate and invoke the function.
>>
>> So I need both the function name as a symbol (to create the delegate) and
>> the function name as a string. In c++ I'd use the preprocessor to convert
>>
>> the symbol to a string via "#" (stringify).
>>
>> If D doesn't have this, the callers will have to do:
>>
>>     register(bob, "bob");
>>
>> which is a little tedious.
>>
>> BTW I tried:
>>
>>   public void register(string name)   {
>>     auto func = __traits(getMember, this, name);
>>
>> but __traits() only works at compile time, but variable name is only
>> available at run-time....
>>
>> John
>>
>
> Okay, I'm a little confused about exactly what you want to do, but I think
> you want something like:
>
> string foo(alias T)() {
>    T++;
>    return T.stringof;
> }
>
> int x = 0;
> assert(foo!x == "x");
> assert(x == 1);
>
> alias template parameters give you access to actual variables/functions,
> which is what you seem to be asking for.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20111023/8b8fb186/attachment-0001.html>


More information about the Digitalmars-d mailing list