ID:2128831
 
BYOND Version:511.1351
Operating System:Windows 10 Pro 64-bit
Web Browser:Chrome 51.0.2704.103
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
Defining top-level "verbs" might be a strange thing to do, but since /verb types do compile, I would expect to find them using typesof(/verb). There shouldn't be any fundamental difference between a proc and a verb. If I define a verb such as /mydatum/verb/myverb(), calling typesof(/mydatum/verb) will return a list containing that verb, even though it was defined under a datum object, which has no verbs list.

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.
Reading this, I'm reminded of my own experiments. Experimenting a bit now,

Your isproc()/isverb() fail on inherited procs;
/datum/proc/foo()
return 1

/datum/bar/foo()
return ..()

/proc/isproc(val)
. = (val in typesof("[copytext("[val]", 1, findtextEx("[val]", "/proc/"))]/proc"))? 1: 0

/proc/isproc2(val)
. = (!istext(val) && text2path("[val]") && findtextEx("[val]", "/proc/") && !istype(val, /datum))? 1: 0

/world/New()
world.log << isproc(/datum/proc/foo) // 1
world.log << isproc(/datum/bar/foo) // 0
world.log << isproc2(/datum/proc/foo) // 1
world.log << isproc2(/datum/bar/foo) // 0


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:
/datum/proc/foo()
set name = "Foo"

/world/New()
var/x = /datum/proc/foo
world.log << x:name // "Foo"
In response to GinjaNinja32
GinjaNinja32 wrote:
Your isproc()/isverb() fails on inherited procs.

Thanks for pointing that out. I somehow overlooked the fact that inherited procs or verbs don't actually include the text "/proc/" or "/verb/" in their paths. Apparently text2path() doesn't work on inherited procs or verbs and typesof() will never return them. This means it is currently impossible to dynamically find references to them at all.

As far as I know, the only objects in DM that have null type vars are world, procs, and verbs, so this should work for now, unless there are very unusual anomalies, or type info is added to procs in the future:
proc/isproc(val)
try
. = (!val:type && val != world)? 1: 0
catch
. = 0

It wouldn't be so simple without using try and catch.

Most of the proc and verb settings are listed in the reference. The only other one I can think of is waitfor.
You can only access name, desc, category and invisibility from a proc or verb object.

For an isproc - it might more more sense to check the \ref of the path. I think they're all 0x26 so you can do something like...
proc/isproc(l)
. = findtext("\ref[l]", "0x26", 2, 6)
// \ref[l] will return a string like [0x26000002]


In response to Super Saiyan X
This GUY.
This GUY.

Genius!

Marvelous, great idea!