Thread overview |
---|
April 14, 2015 CTFE UFCs? | ||||
---|---|---|---|---|
| ||||
Hi. I've been building a reflection library for D, but I've hit a snag. If anyone can help out, it would be much appreciated =D In the example below, the second line of main() retrieves the reflection of a base class. Everything is well and good. Now, I am trying to come up with a more pleasant syntax, which is the code that is commented out. When I uncomment the nicer syntax, I get the errors below: [1] Error: variable refl cannot be read at compile time [2] Error: CTFE failed because of previous errors in base class Base { double d = 0.4; } class Test : Base { int x = 4; } abstract class Refl { @property abstract string name() const; @property abstract string baseName() const; } class ClassRefl(T) : Refl { @property override string name() const { return T.stringof; } @property override string baseName() const { alias BaseClassesTuple!T base_types; return base_types[0].stringof; } } const(Refl) reflect(T)() { static const(Refl) refl = new ClassRefl!T; return refl; } const(Refl) reflect(string name)() { mixin("return reflect!(" ~ name ~ ");"); } //const(Refl) base(const(Refl) refl) { // return reflect!(refl.baseName()); ERROR [1] //} void main() { static const(Refl) refl = reflect!Test; static const(Refl) baseRefl = reflect!(refl.baseName()); //static const(Refl) baseRefl = refl.base; ERROR [2] writeln(refl.name); writeln(baseRefl.name); } If anyone can offer a work around it would be much appreciated. |
April 14, 2015 Re: CTFE UFCs? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bitwise Attachments: | On Tue, 14 Apr 2015 11:20:38 -0400, bitwise wrote: i believe that you can't do what you want in a way you want, 'cause UFCS is not working for template args. but you can do this: alias base(alias CC) = reflect!(CC.baseName()); ... static const(Refl) baseRefl = base!refl; |
April 14, 2015 Re: CTFE UFCs? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bitwise | On Tuesday, 14 April 2015 at 15:20:37 UTC, bitwise wrote:
> When I uncomment the nicer syntax, I get the errors below:
>
> [1] Error: variable refl cannot be read at compile time
> [2] Error: CTFE failed because of previous errors in base
>
>
> class Base {
> double d = 0.4;
> }
>
> class Test : Base {
> int x = 4;
> }
>
> abstract class Refl {
> @property abstract string name() const;
> @property abstract string baseName() const;
> }
>
> class ClassRefl(T) : Refl {
> @property override string name() const {
> return T.stringof;
> }
>
> @property override string baseName() const {
> alias BaseClassesTuple!T base_types;
> return base_types[0].stringof;
> }
> }
>
> const(Refl) reflect(T)() {
> static const(Refl) refl = new ClassRefl!T;
> return refl;
> }
>
> const(Refl) reflect(string name)() {
> mixin("return reflect!(" ~ name ~ ");");
> }
>
> //const(Refl) base(const(Refl) refl) {
> // return reflect!(refl.baseName()); ERROR [1]
> //}
>
> void main()
> {
> static const(Refl) refl = reflect!Test;
>
> static const(Refl) baseRefl = reflect!(refl.baseName());
>
> //static const(Refl) baseRefl = refl.base; ERROR [2]
>
> writeln(refl.name);
> writeln(baseRefl.name);
> }
>
>
> If anyone can offer a work around it would be much appreciated.
Minimal changes to what you have now; gives you `base!refl` instead of `refl.base`:
----
const(Refl) base(alias refl)() {
return reflect!(refl.baseName());
}
static const(Refl) baseRefl = base!refl;
----
Digging deeper:
----
abstract class Refl {
@property abstract string name() const;
immutable(Refl) base() const;
}
class ClassRefl(T) : Refl {
@property override string name() const {
return T.stringof;
}
override immutable(Refl) base() const
{
alias BaseClassesTuple!T base_types;
static if(base_types.length > 0)
{
static immutable(Refl) instance = new ClassRefl!(base_types[0]);
return instance;
}
else return null;
}
}
static const(Refl) baseRefl = refl.base;
----
Parting thoughts:
I don't know where you're heading with this. But so far I don't see what it would buy you over std.traits and TypeInfo/TypeInfo_Class.
|
April 15, 2015 Re: CTFE UFCs? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Tue, 14 Apr 2015 12:46:40 -0400, ketmar <ketmar@ketmar.no-ip.org> wrote:
> On Tue, 14 Apr 2015 11:20:38 -0400, bitwise wrote:
>
> i believe that you can't do what you want in a way you want, 'cause UFCS
> is not working for template args. but you can do this:
>
> alias base(alias CC) = reflect!(CC.baseName());
> ...
> static const(Refl) baseRefl = base!refl;
Yeah.. but at this point you may as well you std.traits.BaseClassesTuple.
|
April 15, 2015 Re: CTFE UFCs? | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Tue, 14 Apr 2015 12:52:19 -0400, anonymous <anonymous@example.com> wrote: > abstract class Refl { > @property abstract string name() const; > immutable(Refl) base() const; > } > > class ClassRefl(T) : Refl { > @property override string name() const { > return T.stringof; > } > > override immutable(Refl) base() const > { > alias BaseClassesTuple!T base_types; > static if(base_types.length > 0) > { > static immutable(Refl) instance = new ClassRefl!(base_types[0]); > return instance; > } > else return null; > } > } > static const(Refl) baseRefl = refl.base; It looks like you ripped this code right out of my current prototype ;) The problem is though, that having the base() method means that "ClassRefl!(base_types[0])" must be instantiated, and that template will also have a base() method, and so will it's base, etc... so reflecting a single class will automatically reflect all bases. I'm trying to get away from this behavior and make reflection total opt-in, meaning that the ClassRefl for the base will only be instantiated if it's actually used. > Parting thoughts: > I don't know where you're heading with this. But so far I don't see what it would buy you over std.traits and TypeInfo/TypeInfo_Class. Because an object-hierarchy is easier to use and self-documenting. Instead of having to look things up, you just type "Reflection" ".", and all the choices of what you can do with the object are presented to you by intellisense. |
April 15, 2015 Re: CTFE UFCs? | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Tue, 14 Apr 2015 12:52:19 -0400, anonymous <anonymous@example.com> wrote: > Parting thoughts: > I don't know where you're heading with this. But so far I don't see what it would buy you over std.traits and TypeInfo/TypeInfo_Class. Forgot to mention support for runtime reflection. See here: https://github.com/bitwise-github/D-Reflection/blob/master/main.d#L14 |
Copyright © 1999-2021 by the D Language Foundation