Somehow, typesof() is broken at top-level, when calling it with /verb as an argument. What is really strange is that it literally returns a list with the /verb type path in it. I can call typesof() for all kinds of types ending with /proc or /verb, but I never get back one of those paths that I used as an argument.
I discovered this blind spot when testing my isproc() and isverb() procs:
proc/isproc(val)
. = (val in typesof("[copytext("[val]", 1, findtextEx("[val]", "/proc/"))]/proc"))? 1: 0
proc/isverb(val)
. = (val in typesof("[copytext("[val]", 1, findtextEx("[val]", "/verb/"))]/verb"))? 1: 0
Obviously isverb() isn't always going to work when some verbs can evade this method of detection.
I can always go back to this ugly, and probably slower, filter method:
proc/isproc(val)
. = (!istext(val) && text2path("[val]") && findtextEx("[val]", "/proc/") && !istype(val, /datum))? 1: 0
proc/isverb(val)
. = (!istext(val) && text2path("[val]") && findtextEx("[val]", "/verb/") && !istype(val, /datum))? 1: 0
I have to check for /datum derived objects in case someone does something funny, like names an object after a proc or verb path.
It's hard to get enough metadata to accurately identify an actual proc or verb. ispath() and istype() are both useless when trying to catch this strange and elusive data type.
Your isproc()/isverb() fail on inherited procs;
The best I can find is:
#define isproc(x) (text2path("[x]") == (x) && !ispath(x))
It shows the same behaviour as your two isproc()s; text2path("/datum/bar/foo") is null.
Lummox, perhaps a built-in isproc() that returns true for procs and verbs, and documentation of what vars are present on these objects? They definitely have a name: