www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - introspection woes (2)

reply "Lloyd Dupont" <ld-REMOVE galador.net> writes:
trying to learn introspection, I have this simple test method:

===================
static void dumpelement(Object o)
{
    if (!o)
        return;

    auto ci = o.classinfo;
    foreach(mi ; ci.getMembers(null))
    {
        writefln("%s . %s", ci.name, mi.name());
    }
}
==================

However it fails to compile with the following error: (any ideas?)
=======
main.d(57): Error: function object.MemberInfo.name () is not callable using 
argument types () const
Building Debug\dtest.exe failed! 
Jun 13 2011
parent reply Johannes Pfau <spam example.com> writes:
Lloyd Dupont wrote:
trying to learn introspection, I have this simple test method:

===================
static void dumpelement(Object o)
{
    if (!o)
        return;

    auto ci = o.classinfo;
    foreach(mi ; ci.getMembers(null))
    {
        writefln("%s . %s", ci.name, mi.name());
    }
}
==================

However it fails to compile with the following error: (any ideas?)
=======
main.d(57): Error: function object.MemberInfo.name () is not callable
using argument types () const
Building Debug\dtest.exe failed! 

Looks like getMembers() returns 'const MemberInfo' but name() is not declared as const. That's likely a bug in druntime, but as a workaround you can try this: ================== writefln("%s . %s", ci.name, (cast(MemberInfo)mi).name()); ================== -- Johannes Pfau
Jun 13 2011
parent reply "Lloyd Dupont" <ld-REMOVE galador.net> writes:
Interesting... I think I understand...
Thanks! :)

However an other problem arise with getMembers() it always returns null!
Looking at the code it seems (from my beginner's perspective) that 
getMembers() rely on the member field (function) xgetMembers which is always 
null, as far as I can tell (didn't see any assignment...)

Anyway of ... making the runtime update xgetMembers?



"Johannes Pfau"  wrote in message 
news:20110613140030.70c8d27b jpf-Satellite-A100...

Lloyd Dupont wrote:
trying to learn introspection, I have this simple test method:

===================
static void dumpelement(Object o)
{
    if (!o)
        return;

    auto ci = o.classinfo;
    foreach(mi ; ci.getMembers(null))
    {
        writefln("%s . %s", ci.name, mi.name());
    }
}
==================

declared as const. That's likely a bug in druntime, but as a workaround you can try this: ================== writefln("%s . %s", ci.name, (cast(MemberInfo)mi).name()); ==================
Jun 13 2011
parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 13/06/2011 13:11, Lloyd Dupont wrote:
 Interesting... I think I understand...
 Thanks! :)

 However an other problem arise with getMembers() it always returns null!
 Looking at the code it seems (from my beginner's perspective) that
 getMembers() rely on the member field (function) xgetMembers which is
 always null, as far as I can tell (didn't see any assignment...)

 Anyway of ... making the runtime update xgetMembers?

My understanding is that xgetMembers is never filled in due to the overhead it would add. You can recompile dmd to support it, but that's a pain. The work around I use is to put a mixin in every class I want to use which uses compile time reflection to build an array which I can access at runtime. Not the most elegant solution. Perhap's a bug report needs opening for this if one isn't already open. -- Robert http://octarineparrot.com/
Jun 13 2011
parent reply "Lloyd Dupont" <ld-REMOVE galador.net> writes:
Thanks Robert!

Mm.. can you (per chance!) share some code?
I'm a newbie and compile time reflection is something which eludes me (so 
far...)!


"Robert Clipsham"  wrote in message news:it4vp1$1n5q$1 digitalmars.com...
 Anyway of ... making the runtime update xgetMembers?

My understanding is that xgetMembers is never filled in due to the overhead it would add. You can recompile dmd to support it, but that's a pain. The work around I use is to put a mixin in every class I want to use which uses compile time reflection to build an array which I can access at runtime. Not the most elegant solution. Perhap's a bug report needs opening for this if one isn't already open.
Jun 13 2011
parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 13/06/2011 13:56, Lloyd Dupont wrote:
 Thanks Robert!

 Mm.. can you (per chance!) share some code?
 I'm a newbie and compile time reflection is something which eludes me
 (so far...)!

See: http://www.digitalmars.com/d/2.0/traits.html ---- class MyClass { void method1(){} void method2(){} } import std.stdio; void main() { foreach (member; __traits(allMembers, MyClass)) writefln("member: %s", member); foreach (member; __traits(derivedMembers, MyClass)) writefln("derived member: %s", member); } ---- Instead of writefln() you can append to an array. You can also make this a bit more generic with: ---- class MyClass { mixin memberArray!MyClass; void method1(){} void method2(){} } import std.stdio; mixin template memberArray(T) { immutable static members = [__traits(derivedMembers, T)]; } void main() { foreach (member; MyClass.members) writefln("member: %s", member); } ---- Hope this helps :) -- Robert http://octarineparrot.com/
Jun 13 2011
parent "Lloyd Dupont" <ld-REMOVE galador.net> writes:
Works a treat!
Thanks for your detailed sample! :)



"Robert Clipsham"  wrote in message news:it5395$2028$1 digitalmars.com... 

See: http://www.digitalmars.com/d/2.0/traits.html
----
class MyClass
{
     void method1(){}
     void method2(){}
}

import std.stdio;

void main()
{
     foreach (member; __traits(allMembers, MyClass))
         writefln("member: %s", member);

     foreach (member; __traits(derivedMembers, MyClass))
         writefln("derived member: %s", member);
}
----

Instead of writefln() you can append to an array. You can also make this 
a bit more generic with:
----
class MyClass
{
     mixin memberArray!MyClass;
     void method1(){}
     void method2(){}
}

import std.stdio;

mixin template memberArray(T)
{
     immutable static members = [__traits(derivedMembers, T)];
}

void main()
{
     foreach (member; MyClass.members)
         writefln("member: %s", member);
}
----

Hope this helps :)

-- 
Robert
http://octarineparrot.com/
Jun 13 2011