ID:702864
 
Not a bug
BYOND Version:493
Operating System:Windows 7 Home Premium 64-bit
Web Browser:Firefox 11.0
Applies to:Dream Maker
Status: Not a bug

This is not a bug. It may be an incorrect use of syntax or a limitation in the software. For further discussion on the matter, please consult the BYOND forums.
Descriptive Problem Summary:
Alright, so hopefully this makes sense.

mob/verb/Find_Mob_By_Tag_In_List()
var/tmp/list/search_list = list()
search_list += src

var/check = locate(src.tag) in search_list
if(check)
world << "Found"
else
world << "Not Found"


Based upon the documentation, the expected behavior for that code snippet would be "find a mob with this tag in this list", and not "find a mob with this tag in the world, and then check to see if that particular instance of the mob is in this list". Right now the latter behavior is what is happening.

I understand that "locate(tag)" returns the first found instance of an atom with that tag in the world, but I would expect "locate(tag) in list" to be searching the list for the atom and not the entire world.

In this demo if you click the Find_Mob_By_Tag_In_List() verb it will return "Found". If you first create a few duplicate mobs (with duplicate tags) using Create_Duplicate_Mob(), then Find_Mob_By_Tag_In_List() will likely return "Not Found".

Demo: http://files.byondhome.com/SilkGames/bugs/TagBug_src.zip
As far as I can tell, the locate(tag) and locate() in list usages weren't actually meant to be mixed. This is more apparent when looking at the reference entry for 'tag', which states the following

This may be assigned to a unique text string identifying a particular object. A reference to the object can then be obtained by using locate().

So working off the assumption that no two identical tags exist, the locate() in list syntax for tags should not be necessary.
Yeah, no two datums should ever have the same tag. The system just doesn't work so hot when that happens. As long as tag is always unique you can locate(tag) without having to check in a specific list.
Nadrew wrote:
Yeah, no two datums should ever have the same tag. The system just doesn't work so hot when that happens. As long as tag is always unique you can locate(tag) without having to check in a specific list.

Whether or not you agree with the methodology does not preclude the existence of a bug. In my case I discovered this due to a bug in our code with mobs with duplicate tags being created elsewhere, but it took me forever to diagnose that as my problem because the documentation seems to indicate that "locate(tag) in list" should work as I outlined above.


From the documentation for locate():

"If a container is given, only objects directly within that object are searched."

The way that the documentation is written, I suppose that it could be interpreted that "locate() in list" only works for atom types and not tags... but that is far from clear. Either the documentation should be clarified, or there is a bug here to fix.
I should also note that it also feels like identifying a list to search is something that we probably had done for the sake of efficiency (whether or not that makes a difference with locate(tag), I don't know). If this is intended behavior, however, I just think that the documentation should make things a bit clearer to avoid future confusion.
I'm inclined to agree that the documentation is unclear in that specific part you mentioned. It should probably be revised to mention that it doesn't matter if it's tag that's specified.

As for the efficiency thing- it doesn't actually make a difference with locate(tag), because as you noted in the original report it ends up evaluating to a locate() plus a boolean, as opposed to the extended locate() syntax. I imagine on the back-end they have some sort of optimization for tagged atoms so that narrowing down the search on the DM end wouldn't make a difference.
From studying the code I conclude the issue is in the documentation, not the code. And it's not actually that the documentation is wrong, but that it doesn't clarify the situation you can get into if you're misusing tags.

You can in fact mix locate(tag) and "in list", and it will return null if the item is not in the list. The problem is, as far as DM is concerned only one object can have the same tag at any given time. So you're not saying "Find an object in this list that has the tag", you're saying "Find THE object with the tag, but only return it if it's in the list."

So if you have two objects with the same tag, this code will fail. If tags are unique as intended, then the code will do exactly what it's supposed to.

[edit]
In the locate() proc's documentation I just added "(must be unique)" to the tag form. The docs are actually pretty thorough here after all. The locate(tag) in list form isn't even listed, although it should work if tags are unique, and the tag var itself does say right up front that it should be a unique identifier.
Lummox JR resolved issue (Not a bug)