www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - IsExpression to check for method

reply John Demme <me teqdruid.com> writes:
OK... So far I'm liking this IsExpression thing, but either I'm hitting
a limitation, or I'm not using it right.  I basically want to determine
if a method exists for a variable.  I want the following snippet to
print "hash", while it currently prints "nohash":
  Object o = new Object;
  static if( is(o.toHash()) ) {
    writefln("hash");
  } else {
    writefln("nohash");
  }
This is in a template, so I can use the type instead of the instance, if
needed.  Is there any way for me to do this?  If there isn't currently,
can it be added?  It'd be really, really useful.  And cool.  BTW, except
for this issue I'm really liking this new addition.  Props to Walter.

Thanks
John Demme
Jun 20 2005
next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
John Demme wrote:
 OK... So far I'm liking this IsExpression thing, but either I'm hitting
 a limitation, or I'm not using it right.  I basically want to determine
 if a method exists for a variable.  I want the following snippet to
 print "hash", while it currently prints "nohash":
   Object o = new Object;
   static if( is(o.toHash()) ) {

It would appear to be a bug that this complies - it isn't among the listed forms of IsExpression. I don't know if there's a way to do it, but I guess it wouldn't be this - it looks related to the _evaluation_ of o.toHash rather than the function itself. I'm guessing that something like this would work static if (is(typeof(&o.toHash) : T delegate())) { ... } but it might not work if the function name is overloaded, depending on how the compiler resolves the typeof. OTOH something like this might work: uint delegate() dummy; static if (is(typeof(dummy = &o.toHash))) { ... } But yes, there ought to be a clear way of doing this. Maybe when I'm in a position to experiment.... Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 21 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
news:d98uen$2tg1$1 digitaldaemon.com...
 John Demme wrote:
 OK... So far I'm liking this IsExpression thing, but either I'm hitting
 a limitation, or I'm not using it right.  I basically want to determine
 if a method exists for a variable.  I want the following snippet to
 print "hash", while it currently prints "nohash":
   Object o = new Object;
   static if( is(o.toHash()) ) {

It would appear to be a bug that this complies - it isn't among the listed forms of IsExpression.

It's a feature, not a bug <g>. The feature is that if the type inside the is( ) parentheses fails to compile *for whatever reason* then the IsExpression result is false. In this case, o.toHash() is not a type, so it fails to compile, and IsExpression returns false. This capability can be manipulated in diverse ways to test for the existence of methods, members, the types of them, etc.
Jun 23 2005
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 23 Jun 2005 22:30:10 -0700, Walter wrote:

 "Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
 news:d98uen$2tg1$1 digitaldaemon.com...
 John Demme wrote:
 OK... So far I'm liking this IsExpression thing, but either I'm hitting
 a limitation, or I'm not using it right.  I basically want to determine
 if a method exists for a variable.  I want the following snippet to
 print "hash", while it currently prints "nohash":
   Object o = new Object;
   static if( is(o.toHash()) ) {

It would appear to be a bug that this complies - it isn't among the listed forms of IsExpression.

It's a feature, not a bug <g>. The feature is that if the type inside the is( ) parentheses fails to compile *for whatever reason* then the IsExpression result is false. In this case, o.toHash() is not a type, so it fails to compile, and IsExpression returns false. This capability can be manipulated in diverse ways to test for the existence of methods, members, the types of them, etc.

Can you supply an example of how to test for the existence of ... ... a module function ... a module variable ... a class member ... a struct member ... a class declaration ... a struct declaration ... a module importation ... a function member -- Derek Melbourne, Australia 24/06/2005 3:40:32 PM
Jun 23 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message
news:w3vzckxoa968.nxmmy66f775t$.dlg 40tude.net...
 This capability can be manipulated in diverse ways to test for the


 of methods, members, the types of them, etc.

Can you supply an example of how to test for the existence of ... ... a module function ... a module variable ... a class member ... a struct member ... a class declaration ... a struct declaration ... a module importation ... a function member

In general, the idea is to construct an expression which will fail to compile if it is *not* one of the above. For example, to test for the existence of member 'm' of struct 'S': static if ( is(typeof(S.m)) ) ...
Jun 24 2005
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Fri, 24 Jun 2005 00:09:21 -0700, Walter wrote:

 "Derek Parnell" <derek psych.ward> wrote in message
 news:w3vzckxoa968.nxmmy66f775t$.dlg 40tude.net...
 This capability can be manipulated in diverse ways to test for the


 of methods, members, the types of them, etc.

Can you supply an example of how to test for the existence of ... ... a module function ... a module variable ... a class member ... a struct member ... a class declaration ... a struct declaration ... a module importation ... a function member

In general, the idea is to construct an expression which will fail to compile if it is *not* one of the above. For example, to test for the existence of member 'm' of struct 'S': static if ( is(typeof(S.m)) ) ...

But that is exactly what I'd like to prevent! In other words I'd like to do this sort of thing ... static_if (! exists(S.m)) { // declare 'm' } -- Derek Melbourne, Australia 24/06/2005 5:21:06 PM
Jun 24 2005
parent reply Sean Kelly <sean f4.ca> writes:
In article <1f1np8srt6jk1.j36513qm0sd7.dlg 40tude.net>, Derek Parnell says...
On Fri, 24 Jun 2005 00:09:21 -0700, Walter wrote:

 "Derek Parnell" <derek psych.ward> wrote in message
 news:w3vzckxoa968.nxmmy66f775t$.dlg 40tude.net...
 This capability can be manipulated in diverse ways to test for the


 of methods, members, the types of them, etc.

Can you supply an example of how to test for the existence of ... ... a module function ... a module variable ... a class member ... a struct member ... a class declaration ... a struct declaration ... a module importation ... a function member

In general, the idea is to construct an expression which will fail to compile if it is *not* one of the above. For example, to test for the existence of member 'm' of struct 'S': static if ( is(typeof(S.m)) ) ...

But that is exactly what I'd like to prevent! In other words I'd like to do this sort of thing ... static_if (! exists(S.m)) { // declare 'm' }

I like the new features, but using "is" in this way (since it's also a non-static binary operator) is somewhat confusing. In some respects I'd prefer a new keyowrd for this purpose--istype perhaps? That said, I think we may need the implementation as it is now if it's to work effectively with template code. Consider this (bad) example: # class A { # alias int T; # } # # class B { # int T() {} # } # # template Eval(E) { # static if( is(E.T) ) {} # } # # Eval!(A); # Eval!(B); Here we're filtering on whether or not E.T is a type, rather than whether E.T exists at all (and I just realized I could make a terrible joke about aliens, but I'm resisting the urge). Sean
Jun 24 2005
parent pragma <pragma_member pathlink.com> writes:
In article <d9hb8g$2ucm$1 digitaldaemon.com>, Sean Kelly says...
In article <1f1np8srt6jk1.j36513qm0sd7.dlg 40tude.net>, Derek Parnell says...
But that is exactly what I'd like to prevent! In other words I'd like to do
this sort of thing ...

  static_if (! exists(S.m))
  {
      // declare 'm'
  }

I like the new features, but using "is" in this way (since it's also a non-static binary operator) is somewhat confusing. In some respects I'd prefer a new keyowrd for this purpose--istype perhaps?

I agree. D should probably use something like istype(), exists(), or just anything_other_than_is(). Overloading 'is' like this is a tad confusing to the eye. At first glance, it just doesn't look like valid D code (IMO). - EricAnderton at yahoo
Jun 24 2005
prev sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
Aha!  This is what I got wrong when testing for function existance.

I don't mean to repeat myself, but is this going to find its way into 
the documentation?  I would argue it's very useful (in fact I did, 
possibly not-to-successfully.)

-[Unknown]


     static if ( is(typeof(S.m)) )
         ...

Jun 24 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Unknown W. Brackets" <unknown simplemachines.org> wrote in message
news:d9hdfk$30f5$2 digitaldaemon.com...
 Aha!  This is what I got wrong when testing for function existance.

 I don't mean to repeat myself, but is this going to find its way into
 the documentation?  I would argue it's very useful (in fact I did,
 possibly not-to-successfully.)

It's in the documentation: "The condition is satisfied if Type is semantically correct (it must be syntactically correct regardless)."
Jun 24 2005
parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
Well, then, forgive me for being daft but upon reading that twice I 
still did not consider that it could be used to check for the existance 
of functions, types, and methods which do not currently exist.

I now understand that, but it seems like a more useful feature than just 
one sentence.  Maybe the documentation could at least describe that this:

int main()
{
    static if (is(typeof(someTypeOrFunctionThatDoesNotExist)))
       writef("This will never be output.");

    static if (is(typeof(Object.someMethodOrMemberThatDoesNotExist)))
       writef("This will never be output either.");
}

Will compile (and run) fine.  You could probably give a better example, 
though.

I just mean that the word "type" is used quite a number of times in the 
IsExpression documentation, and it is not immediately logical that this 
means that a typeof expression can be used with a value that does not exist.

Now that I understand this, the various forms of is() make much more 
sense, in fact this looks interesting:

     static if (is(typeof(myfunc) T))
         T* myfunc_fp = &myfunc;

-[Unknown]


 "Unknown W. Brackets" <unknown simplemachines.org> wrote in message
 news:d9hdfk$30f5$2 digitaldaemon.com...
 
Aha!  This is what I got wrong when testing for function existance.

I don't mean to repeat myself, but is this going to find its way into
the documentation?  I would argue it's very useful (in fact I did,
possibly not-to-successfully.)

It's in the documentation: "The condition is satisfied if Type is semantically correct (it must be syntactically correct regardless)."

Jun 24 2005
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Walter wrote:
 "Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
 news:d98uen$2tg1$1 digitaldaemon.com...

It would appear to be a bug that this complies - it isn't among the
listed forms of IsExpression.

It's a feature, not a bug <g>. The feature is that if the type inside the is( ) parentheses fails to compile *for whatever reason* then the IsExpression result is false.

For whatever reason? Then static if (is(/.,mnbv\][)) { ... } should compile?
 In this case, o.toHash() is not a type, so it fails to compile, and
 IsExpression returns false.

You tell us that the IsExpression must be syntactically valid regardless. IsExpression: is ( Type ) is ( Type : TypeSpecialization ) is ( Type == TypeSpecialization ) is ( Type Identifier ) is ( Type Identifier : TypeSpecialization ) is ( Type Identifier == TypeSpecialization ) The OP's code isn't parseable as any of these, so according to this it's a syntax error.
 This capability can be manipulated in diverse ways to test for the existence
 of methods, members, the types of them, etc.

-- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 24 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
news:d9gj4d$1vge$1 digitaldaemon.com...
 Walter wrote:
 "Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
 news:d98uen$2tg1$1 digitaldaemon.com...

It would appear to be a bug that this complies - it isn't among the
listed forms of IsExpression.

It's a feature, not a bug <g>. The feature is that if the type inside


 is( ) parentheses fails to compile *for whatever reason* then the
 IsExpression result is false.

For whatever reason? Then static if (is(/.,mnbv\][)) { ... } should compile?

No, as that is not syntactically correct.
 In this case, o.toHash() is not a type, so it fails to compile, and
 IsExpression returns false.

You tell us that the IsExpression must be syntactically valid regardless.

Yes. I miswrote the "for whatever reason", as it still must be syntactically valid.
Jun 24 2005
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Walter wrote:
 "Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
 news:d9gj4d$1vge$1 digitaldaemon.com...

For whatever reason?  Then

     static if (is(/.,mnbv\][)) { ... }

should compile?

No, as that is not syntactically correct.

Exactly. Neither is the OP's snippet according to the forms of IsExpression allowed by the spec. Or is o.toHash() parseable as a type by some obscure feature none of us have discovered? Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 24 2005
next sibling parent Sean Kelly <sean f4.ca> writes:
In article <d9hgh1$2j4$1 digitaldaemon.com>, Stewart Gordon says...
Or is

     o.toHash()

parseable as a type by some obscure feature none of us have discovered?

I was wondering about this as well. Sean
Jun 24 2005
prev sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
news:d9hgh1$2j4$1 digitaldaemon.com...
 Walter wrote:
 "Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
 news:d9gj4d$1vge$1 digitaldaemon.com...

For whatever reason?  Then

     static if (is(/.,mnbv\][)) { ... }

should compile?

No, as that is not syntactically correct.

Exactly. Neither is the OP's snippet according to the forms of IsExpression allowed by the spec. Or is o.toHash() parseable as a type by some obscure feature none of us have discovered?

No, it isn't parseable as a type.
Jun 24 2005
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Walter wrote:
 "Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
 news:d9hgh1$2j4$1 digitaldaemon.com...

 Or is

      o.toHash()

 parseable as a type by some obscure feature none of us have discovered?

No, it isn't parseable as a type.

Exactly. Therefore is(o.toHash()) isn't a syntactically valid IsExpression. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jul 11 2005
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
John Demme wrote:
 OK... So far I'm liking this IsExpression thing, but either I'm hitting
 a limitation, or I'm not using it right.  I basically want to determine
 if a method exists for a variable.

This code tests for the presence of a method having the given signature. The dummy delegate is needed to disambiguate between overloadings. ---------- import std.stdio; class Qwert { void yuiop(int asdfg) {} int yuiop() { return 0; } } void main() { Qwert hjkl; //void delegate(int) zxcvb; //real delegate(char[]) zxcvb; int delegate() zxcvb; static if (is(typeof(zxcvb = &hjkl.yuiop))) { writefln("yes"); } else { writefln("no"); } } ---------- OTOH, if you merely want to test for the presence of a method with a given name without caring about its signature (don't ask me why you'd want to do this), static if (is(typeof(&hjkl.yuiop))) is adequate. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 22 2005