Thread overview
introspection woes (2)
Jun 13, 2011
Lloyd Dupont
Jun 13, 2011
Johannes Pfau
Jun 13, 2011
Lloyd Dupont
Jun 13, 2011
Robert Clipsham
Jun 13, 2011
Lloyd Dupont
Jun 13, 2011
Robert Clipsham
Jun 13, 2011
Lloyd Dupont
June 13, 2011
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! 

June 13, 2011
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

June 13, 2011
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());
>    }
>}
>==================
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());
==================

June 13, 2011
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/
June 13, 2011
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.

June 13, 2011
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/
June 13, 2011
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/