Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 30, 2007 Determining whether a class has a method | ||||
---|---|---|---|---|
| ||||
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? |
November 30, 2007 Re: Determining whether a class has a method | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | 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
|
November 30, 2007 Re: Determining whether a class has a method | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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.
|
November 30, 2007 Re: Determining whether a class has a method | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright |
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
|
November 30, 2007 Re: Determining whether a class has a method | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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
>> 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
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!
|
November 30, 2007 Re: Determining whether a class has a method | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | "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. |
November 30, 2007 Re: Determining whether a class has a method | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | 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?
|
November 30, 2007 Re: Determining whether a class has a method | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | "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. |
November 30, 2007 Re: Determining whether a class has a method | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | 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?
>>> 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.
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];
|
November 30, 2007 Re: Determining whether a class has a method | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | 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?
>>>> 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.
>
> 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
|
Copyright © 1999-2021 by the D Language Foundation