January 20, 2009
BCS schrieb:
> you can get the names even in D1.0. Not exactly clean but...
> 
> http://codepad.org/Eu16XqFu

Yeah but only works for structs. When used with classes returns an ExpressionTuple. Furthermore you only get the fields, I need the methods ;)
January 20, 2009
It seems like there is no way to automatically get the class methods in D1 currently?!
__traits isn't supported, std.traits doesn't give anything usable, .tupleof only gets the fields (plus only giving an ExpressionTuple for classes).
January 20, 2009
On Tue, Jan 20, 2009 at 10:29 AM, Trass3r <mrmocool@gmx.de> wrote:
> It seems like there is no way to automatically get the class methods in D1
> currently?!
> __traits isn't supported, std.traits doesn't give anything usable, .tupleof
> only gets the fields (plus only giving an ExpressionTuple for classes).

You're correct.  __traits was introduced in D2 mostly because D1's compile-time introspection is so paltry.
January 20, 2009
Jarrett Billingsley schrieb:
> On Tue, Jan 20, 2009 at 10:29 AM, Trass3r <mrmocool@gmx.de> wrote:
>> It seems like there is no way to automatically get the class methods in D1
>> currently?!
>> __traits isn't supported, std.traits doesn't give anything usable, .tupleof
>> only gets the fields (plus only giving an ExpressionTuple for classes).
> 
> You're correct.  __traits was introduced in D2 mostly because D1's
> compile-time introspection is so paltry.

Yeah, __traits works quite well to get the function names, but I still can't manage to get the corresponding function object to pass it to ParameterTypeTuple (for checking the parameters for correctness).

Tried using ClassInfo's getMembers function but that apparently doesn't work.

Base base = new Base;
auto members = __traits(allMembers, typeof(base));
foreach(m; members)
	writefln(base.classinfo.getMembers(m).length);

gives 0 for every member :(
January 20, 2009
On Tue, Jan 20, 2009 at 2:13 PM, Trass3r <mrmocool@gmx.de> wrote:
> Yeah, __traits works quite well to get the function names, but I still can't manage to get the corresponding function object to pass it to ParameterTypeTuple (for checking the parameters for correctness).

Ah, that's what __traits(getMember) is for.  You pass it an object/class and a string of the member name, and it gives you what it corresponds to.

> Tried using ClassInfo's getMembers function but that apparently doesn't work.
>
> Base base = new Base;
> auto members = __traits(allMembers, typeof(base));
> foreach(m; members)
>        writefln(base.classinfo.getMembers(m).length);
>
> gives 0 for every member :(

I think that's actually a bug.  DMD doesn't generate that info for some reason.  I think LDC does.
January 20, 2009
Jarrett Billingsley schrieb:
> On Tue, Jan 20, 2009 at 2:13 PM, Trass3r <mrmocool@gmx.de> wrote:
>> Yeah, __traits works quite well to get the function names, but I still can't
>> manage to get the corresponding function object to pass it to
>> ParameterTypeTuple (for checking the parameters for correctness).
> 
> Ah, that's what __traits(getMember) is for.  You pass it an
> object/class and a string of the member name, and it gives you what it
> corresponds to.
> 

OMG, I've already seen this function in the docs some time ago but somehow I couldn't remember.
Many thanks!
January 21, 2009
Jarrett Billingsley wrote:
> On Tue, Jan 20, 2009 at 10:29 AM, Trass3r <mrmocool@gmx.de> wrote:
>> It seems like there is no way to automatically get the class methods in D1
>> currently?!
>> __traits isn't supported, std.traits doesn't give anything usable, .tupleof
>> only gets the fields (plus only giving an ExpressionTuple for classes).
> 
> You're correct.  __traits was introduced in D2 mostly because D1's
> compile-time introspection is so paltry.

But unless you're doing very basic stuff or only touching a few classes, compile-time introspection ends up being quite costly. I want runtime reflection for that reason.

On the other hand, you can get the non-final, non-private methods of a class with something like:
foreach (member; __traits (allMembers, Class))
{
	foreach (overload; __traits (getVirtualFunctions, Class, member))
	{
		// do stuff
	}
}

Naturally, __traits and foreach don't mix, so you'll have to use template recursion. This is pretty damn ugly.

Note that getVirtualFunctions returns methods that are not virtual. You need to use isVirtualFunction to determine whether a method is virtual.
January 21, 2009
On Tue, Jan 20, 2009 at 7:42 PM, Christopher Wright <dhasenan@gmail.com> wrote:

> Naturally, __traits and foreach don't mix, so you'll have to use template recursion. This is pretty damn ugly.

I never understood why __traits likes returning arrays so much.  Why not tuples?

> Note that getVirtualFunctions returns methods that are not virtual. You need to use isVirtualFunction to determine whether a method is virtual.

Lol.
January 21, 2009
Christopher Wright schrieb:
> On the other hand, you can get the non-final, non-private methods of a class with something like:
> foreach (member; __traits (allMembers, Class))
> {
>     foreach (overload; __traits (getVirtualFunctions, Class, member))
>     {
>         // do stuff
>     }
> }
> 
> Naturally, __traits and foreach don't mix, so you'll have to use template recursion. This is pretty damn ugly.
> 

But why doesn't that work? It doesn't even work when forced to run at compile time by CTFE.
Had a look at the compiler code, it uses the same mechanism as pragma(msg, for example, so shouldn't something like the above theoretically be possible?
January 26, 2009
Wed, 21 Jan 2009 12:48:07 +0100, Trass3r wrote:

> Christopher Wright schrieb:
>> On the other hand, you can get the non-final, non-private methods of a
>> class with something like:
>> foreach (member; __traits (allMembers, Class))
>> {
>>     foreach (overload; __traits (getVirtualFunctions, Class, member))
>>     {
>>         // do stuff
>>     }
>> }
>> 
>> Naturally, __traits and foreach don't mix, so you'll have to use template recursion. This is pretty damn ugly.
>> 
> 
> But why doesn't that work? It doesn't even work when forced to run at
> compile time by CTFE.
> Had a look at the compiler code, it uses the same mechanism as
> pragma(msg, for example, so shouldn't something like the above
> theoretically be possible?

foreach() is a runtime construct.  It may be *interpreted* at compile-time, but it's interpreted as if it were run time nevertheless. It dynamically changes the value of 'member' variable.

pragma() and __traits() are compile-time constructs.  They are fully and
statically expanded before anything is being interpreted and cannot
handle dynamically changing variables.