digitalmars.D.learn - Determining whether a class has a method
- Christopher Wright <dhasenan gmail.com> Nov 29 2007
- Bill Baxter <dnewsgroup billbaxter.com> Nov 29 2007
- Christopher Wright <dhasenan gmail.com> Nov 29 2007
- Daniel Keep <daniel.keep.lists gmail.com> Nov 29 2007
- Christopher Wright <dhasenan gmail.com> Nov 29 2007
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Nov 29 2007
- Christopher Wright <dhasenan gmail.com> Nov 29 2007
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Nov 29 2007
- Christopher Wright <dhasenan gmail.com> Nov 29 2007
- Bill Baxter <dnewsgroup billbaxter.com> Nov 29 2007
- Christopher Wright <dhasenan gmail.com> Nov 29 2007
Hey all,
I'm trying to determine whether a class has a method (at compile time,
based on the name), and ideally I want to do this is D1 as well as D2.
In D2, I can just use __traits, of course.
I could try doing something like:
bool has_method(T, string name)() {
foreach (method; T.tupleof) {
if (method.stringof == name) {
return true;
}
}
return false;
}
But tupleof fails if you give it a class that has fields (methods are
fine, but data fields aren't). I'm pretty sure this is a bug; can anyone
else comment on it?
Is there a way to do this in D1?
Nov 29 2007
Christopher Wright wrote:Hey all, I'm trying to determine whether a class has a method (at compile time, based on the name), and ideally I want to do this is D1 as well as D2. In D2, I can just use __traits, of course. I could try doing something like: bool has_method(T, string name)() { foreach (method; T.tupleof) { if (method.stringof == name) { return true; } } return false; } But tupleof fails if you give it a class that has fields (methods are fine, but data fields aren't). I'm pretty sure this is a bug; can anyone else comment on it? Is there a way to do this in D1?
I think you may be able to use an 'is' check + string mixin if the name string is a compile time constant. like static if(is( T.name == function )) then mixin-ify that like bool has_method(T, string name) { mixin("static if(is T."~name~" == function)) " "{ return true; } else {return false; }"); } --bb
Nov 29 2007
Bill Baxter wrote:I think you may be able to use an 'is' check + string mixin if the name string is a compile time constant. like static if(is( T.name == function )) then mixin-ify that like bool has_method(T, string name) { mixin("static if(is T."~name~" == function)) " "{ return true; } else {return false; }"); } --bb
Very nice! It works for every situation but the one I need: static if (is (T._ctor == function)) { // This never happens. } If there's no constructor defined for a class or any of its base classes, then ParameterTypeTuple!(T._ctor) fails, of course. I guess I can work around this by requiring an explicit constructor, but I don't love it, especially since I can't provide a helpful error message in the failing case.
Nov 29 2007
Christopher Wright wrote:Bill Baxter wrote:I think you may be able to use an 'is' check + string mixin if the name string is a compile time constant. like static if(is( T.name == function )) then mixin-ify that like bool has_method(T, string name) { mixin("static if(is T."~name~" == function)) " "{ return true; } else {return false; }"); } --bb
Very nice! It works for every situation but the one I need: static if (is (T._ctor == function)) { // This never happens. } If there's no constructor defined for a class or any of its base classes, then ParameterTypeTuple!(T._ctor) fails, of course. I guess I can work around this by requiring an explicit constructor, but I don't love it, especially since I can't provide a helpful error message in the failing case.
Can't you do something like: static if( is( typeof(new T) == T ) ) ... That should fail if T doesn't have a zero-arg constructor, at least AFAIK. -- Daniel
Nov 29 2007
Daniel Keep wrote:Christopher Wright wrote:Bill Baxter wrote:I think you may be able to use an 'is' check + string mixin if the name string is a compile time constant. like static if(is( T.name == function )) then mixin-ify that like bool has_method(T, string name) { mixin("static if(is T."~name~" == function)) " "{ return true; } else {return false; }"); } --bb
static if (is (T._ctor == function)) { // This never happens. } If there's no constructor defined for a class or any of its base classes, then ParameterTypeTuple!(T._ctor) fails, of course. I guess I can work around this by requiring an explicit constructor, but I don't love it, especially since I can't provide a helpful error message in the failing case.
Can't you do something like: static if( is( typeof(new T) == T ) ) ... That should fail if T doesn't have a zero-arg constructor, at least AFAIK. -- Daniel
With the implication that, if I have a zero-arg constructor, I can just use that, and if I don't, then I can safely call ParameterTypeTuple on it. Thanks!
Nov 29 2007
"Christopher Wright" <dhasenan gmail.com> wrote in message news:fink7k$6ph$1 digitalmars.com...But tupleof fails if you give it a class that has fields (methods are fine, but data fields aren't). I'm pretty sure this is a bug; can anyone else comment on it?
tupleof is supposed to give you a tuple of fields. It will never give methods.
Nov 29 2007
Jarrett Billingsley wrote:"Christopher Wright" <dhasenan gmail.com> wrote in message news:fink7k$6ph$1 digitalmars.com...But tupleof fails if you give it a class that has fields (methods are fine, but data fields aren't). I'm pretty sure this is a bug; can anyone else comment on it?
tupleof is supposed to give you a tuple of fields. It will never give methods.
And it's supposed to work for classes?
Nov 29 2007
"Christopher Wright" <dhasenan gmail.com> wrote in message news:finqpt$lnj$2 digitalmars.com...Jarrett Billingsley wrote:"Christopher Wright" <dhasenan gmail.com> wrote in message news:fink7k$6ph$1 digitalmars.com...But tupleof fails if you give it a class that has fields (methods are fine, but data fields aren't). I'm pretty sure this is a bug; can anyone else comment on it?
tupleof is supposed to give you a tuple of fields. It will never give methods.
And it's supposed to work for classes?
Yes. It's all in the spec: Class Properties The .tupleof property returns an ExpressionTuple of all the fields in the class, excluding the hidden fields and the fields in the base class.
Nov 29 2007
Jarrett Billingsley wrote:"Christopher Wright" <dhasenan gmail.com> wrote in message news:finqpt$lnj$2 digitalmars.com...Jarrett Billingsley wrote:"Christopher Wright" <dhasenan gmail.com> wrote in message news:fink7k$6ph$1 digitalmars.com...But tupleof fails if you give it a class that has fields (methods are fine, but data fields aren't). I'm pretty sure this is a bug; can anyone else comment on it?
methods.
Yes. It's all in the spec: Class Properties The .tupleof property returns an ExpressionTuple of all the fields in the class, excluding the hidden fields and the fields in the base class.
Ah. Then it's not supposed to generate an error: Error: type Foo is not an expression For reference, here's the code, and I think it's not my error: class Foo { // Comment the following line to eliminate the error: // Error: type Foo is not an expression int i; } foreach (blah; Foo.tupleof) { writefln("%s", blah.stringof); } // or: auto a = Foo.tupleof[0];
Nov 29 2007
Christopher Wright wrote:Jarrett Billingsley wrote:"Christopher Wright" <dhasenan gmail.com> wrote in message news:finqpt$lnj$2 digitalmars.com...Jarrett Billingsley wrote:"Christopher Wright" <dhasenan gmail.com> wrote in message news:fink7k$6ph$1 digitalmars.com...But tupleof fails if you give it a class that has fields (methods are fine, but data fields aren't). I'm pretty sure this is a bug; can anyone else comment on it?
give methods.
Yes. It's all in the spec: Class Properties The .tupleof property returns an ExpressionTuple of all the fields in the class, excluding the hidden fields and the fields in the base class.
Ah. Then it's not supposed to generate an error: Error: type Foo is not an expression For reference, here's the code, and I think it's not my error: class Foo { // Comment the following line to eliminate the error: // Error: type Foo is not an expression int i; } foreach (blah; Foo.tupleof) { writefln("%s", blah.stringof); } // or: auto a = Foo.tupleof[0];
Foo is a type. So Foo.tupleof would be a type tuple (if anything -- I'm not sure that works, though it does for structs). You probably need auto a = (new Foo).tupleof[0]; --bb
Nov 29 2007
Bill Baxter wrote:Christopher Wright wrote:Jarrett Billingsley wrote:"Christopher Wright" <dhasenan gmail.com> wrote in message news:finqpt$lnj$2 digitalmars.com...Jarrett Billingsley wrote:"Christopher Wright" <dhasenan gmail.com> wrote in message news:fink7k$6ph$1 digitalmars.com...But tupleof fails if you give it a class that has fields (methods are fine, but data fields aren't). I'm pretty sure this is a bug; can anyone else comment on it?
give methods.
Yes. It's all in the spec: Class Properties The .tupleof property returns an ExpressionTuple of all the fields in the class, excluding the hidden fields and the fields in the base class.
Ah. Then it's not supposed to generate an error: Error: type Foo is not an expression For reference, here's the code, and I think it's not my error: class Foo { // Comment the following line to eliminate the error: // Error: type Foo is not an expression int i; } foreach (blah; Foo.tupleof) { writefln("%s", blah.stringof); } // or: auto a = Foo.tupleof[0];
Foo is a type. So Foo.tupleof would be a type tuple (if anything -- I'm not sure that works, though it does for structs). You probably need auto a = (new Foo).tupleof[0]; --bb
If you want to use it as a type, though, you have to do typeof(Foo.tupleof[0]). But you still can't do (Foo.tupleof[0]).stringof ("Error: Foo.tupleof is used as a type").
Nov 29 2007









Christopher Wright <dhasenan gmail.com> 