ID:1493127
 
(See the best response by Kaiochao.)
Code:
mob/verb/test()
var/obj/O = new()
O.tag = "My Object"

var/obj/O2 = locate("My Object")

ASSERT(O == O2) //this should always be true


Problem description:

When I execute this code shown in the reference once it returns true. If I execute it once more or after it returns false. I assume it is because of the garbage collector but wanted to be sure it wasn't something else.

Setting O.tag to null allows me to use this procedure again and have it return true.

mob/verb/test()
var/obj/O = new()
O.tag = "My Object"

var/obj/O2 = locate("My Object")

ASSERT(O == O2) //this should always be true
O.tag = null


All I can think of it being is something where O.tag is set to "My Object" twice somehow- maybe like a list? Am I on the right track?
The first O created isn't garbage collected because it has a tag. The second one will have conflicting tags with the first one; who knows which one will be found by locate().
How do you visualize that? Is it a list or something?

Edit: Is the tag variable considered a list?
Just reiteration of what Kaiochao already said: The garbage collector cleans up things that will no longer be used. It does this when an entity no longer has any references to it. The "tag" variable is such a reference, so as long as that variable is set to equal something, it will only ever be removed if you delete it yourself.

Now with that said, when you call the verb a second time, that first object still exists in the world with (and because of) the tag set to "My Object". However, you create a second object and also assign it's tag to "My Object". Now the SECOND time your verb calls "locate("My Object")" there exists two objects in the world of the same type with the same tag. If the specific object locate() finds is NOT the one you just created in the second call of your test() verb, then the ASSERT() is going to fail. I hope this clarifies things.

*edit*
I can't think of an instance contrary so I'll just generalize and say that you should be careful not to have two objects with the same tag (at the same time).
In response to Sir Quizalot
Off the top of my head, when you use locate(tag), it's like doing this (of course, much faster):
//  locate(tag) returns the object with the tag specified
proc/locate(tag)
// search through all objects in existence
for(var/datum/d)
// if the tag matches, return this object
if(d.tag == tag)
return d

// since locate() can only return one object,
// other objects with the same tag are not reached.

There's no reason for you to think "tag" is a list. I don't know how you even came up with that. The "tag" variable is a string.
In response to Koshigia
So it's a list and positional order. The oldest instances created is used in the locate(Tag). Yet this procedure requires the current instance for locate(Tag) for ASSERT(expression)to return true.

Edit: Obviously it can retain a list of strings considering what it does in first posted code.
In response to Sir Quizalot
It's not really a list, and I wouldn't use that as an analogy to prevent confusion with what an actual list is. Refer to Kaiochao's post to understand the mechanics of the locate() procedure. It's commented as well to ease understanding.

In my opinion, it's also not always good idea to rely on a procedure to do something it was not intended to do. There are safer ways to do things than having multiple objects with the same tag.
If it's not a list what is it called?

locate(Tag) // search through all objects in existence

tag var (datum) //This may be assigned to a unique text string identifying a particular object.

tag apparently can be assigned to more then one unique text string at a time based on first posted code.

locate() goes through a "list?" of objects in existence according to Kaiochao's post.

Edit: Having multiple objects with the same tag doesn't make sense. That is not my goal. My goal is to understand these references better based on the questions I have shown here.
In response to Sir Quizalot
You've been saying the "tag" var is a list, which is incorrect.

The locate() proc returns a single object with a matching tag. We don't know exactly how it does this (maybe it uses a list, maybe it doesn't), and it doesn't really matter.

All you need to know is that it doesn't make sense to have multiple objects with the same "unique" tag. You shouldn't expect to get results that make sense from doing something that doesn't make sense.
In response to Sir Quizalot
Sir Quizalot wrote:
tag apparently can be assigned to more then one unique text string at a time based on first posted code.
This doesn't make sense. A variable can only be set to one value at a time. Maybe you meant to say "multiple objects can have the same unique tag," which is possible, but is impractical.

The objects in the verb are created inside each verb and are separate from the previous objects created from other uses of the verb.
In response to Kaiochao
So you don't know okay. I can live with the results for now. If anyone else who does know can help please do.


Kaiochao wrote:

The locate() proc returns a single object with a matching tag. We don't know exactly how it does this (maybe it uses a list, maybe it doesn't), and it doesn't really matter.



In the above code tag is assigned to more then one unique text string after using the verb more then once.

This doesn't make sense. A variable can only be set to one value at a time.
In response to Sir Quizalot
The verb creates a completely new object every time the verb is used.

The newly-created object has its tag variable set to a string. The string used here just happens to be the same as the previously-created object's tag variable.

Saying "tag is assigned to more then one unique text string" makes absolutely no sense at all. It's not the same tag variable and there's only one value being used. Maybe you're just using the wrong words, but I can't guess what you're actually talking about.
Kaiochao has accurately answered your question multiple times, with in-depth descriptions of how tag works in front-end.
What more do you want?
Something is retaining more then one value

1. (My guess is tag)

2. (new() doesn't add anything to a default list so it can't be because of new() that they're two retained values of O.)

3. Or something is looking for something that isn't there (my guess locate()).


Which one is happening?

Either way the procedure in the first code posted doesn't work on second iteration due to a value not being the one requested which means something's value didn't change the second iteration. Otherwise ASSERT(O == O2) should have returned true on second iteration of the procedure and iterations after.
In response to Sir Quizalot
Best response
It's been pretty obvious from the start what's causing the second assertion to fail.

The first time you use the verb, an object is created with the tag "My Object".

The second time you use the verb, another object is created with the tag "My Object". The first object created still exists in the world with the tag "My Object". Then, locate("My Object") is getting the first object, not the object that was just created.

The only list involved here could be world.contents, which contains every object in existence, including the object created the first time the verb is used, as well as the object created the second time.

Of course, this does not mean tag (which is a variable attached to objects) is "retaining" any value other than what it's set to.

So,
2. (new() doesn't add anything to a default list so it can't be because of new() that they're two retained values of O.)
Since new() adds objects to "the list of objects in existence" (aka world.contents), I'd say this is your answer.
So new() is adding to world contents by default? How can you tell?
Run this:

var/objects = 0


mob/verb/test()
var/obj/O = new()
O.tag = "My Object"
O.name = "object [++objects]"

var/obj/O2 = locate("My Object")
world << "[O.name] == [O2.name]"


Each time you're using the test() verb, a new object with the same tag is being created. When you have multiple objects with the same tag, it will give unexpected results. Each tag is SUPPOSED to be unique to the world.

I'm not exactly sure how locate() works on the backend, but it's not going to point to the same object each time you use it.

Here is an output of what happens with my snippet:

(left is always the new object, right is always the locate())
object 1 == object 1
object 2 == object 1
object 3 == object 2
object 4 == object 2
object 5 == object 2
object 6 == object 2
object 7 == object 2
object 8 == object 4
object 9 == object 4
object 10 == object 4
object 11 == object 4
object 12 == object 4
object 13 == object 4
object 14 == object 4
object 15 == object 4
object 16 == object 4
object 17 == object 4
object 18 == object 8
object 19 == object 8
object 20 == object 8
object 21 == object 8
object 22 == object 8
object 23 == object 8
object 24 == object 8
object 25 == object 8
object 26 == object 8
object 27 == object 8
object 28 == object 8
object 29 == object 8
object 30 == object 8
object 31 == object 8
object 32 == object 8
object 33 == object 8
object 34 == object 8
object 35 == object 8
object 36 == object 8
object 37 == object 8
object 38 == object 16
object 39 == object 16
object 40 == object 16


Clearly, there's kind of algorithm that decides which object with a matching tag to pick. You shouldn't care about that, though. Just be sure there is only object, per world, with a certain tag.

Sir Quizalot wrote:
So new() is adding to world contents by default? How can you tell?

All atoms are added to the world's contents. Every single one of them.
In response to Sir Quizalot
I'll try one more time, this time more simplified instead of in-depth. Again, all of this has been said before by Kaiochao.

Every time you use the verb, a brand new object is created. These objects never get deleted BECAUSE you assigned their tag variable.

So, let's say you used the verb 3 times. That means you'd have three objects floating around somewhere in the world, and ALL three of them would have the same string assigned to their respective tag variables ("My Object"). So one more time... you'd have three objects all tagged as "My Object"... Three separate existences.

Now, this is how locate("<string>") works: It tries to find some object in the world with "<string>" as it's tag. That's fine and dandy, except that you have THREE of them floating around all with the same tag.

This was not how tag was intended to work. Tag was intended as a way for you to UNIQUELY identify some entity in your world. It's not unique anymore because you called the verb multiple times, thereby creating multiple objects.

So basically, you are trying to locate a unique object that is not unique. Try this bit of code to help if you still do not understand:

mob/verb/test()
//first lets check to see if "My Object" already exists before creating a new one.
var/obj/O = locate("My Object")

//if O did not exist already
if(!O)
O = new() //create a new one
O.tag = "My Object" // and tag it as "My Object" (Now we know that O is unique)

var/obj/O2 = locate("My Object")

ASSERT(O == O2) //this should always be true


In this example, a new object is only created if one doesn't already exist. If you wanted to ALWAYS make a new object and still keep it unique, this would be a way to do that.

mob/verb/test()
//first lets check to see if "My Object" already exists before creating a new one.
var/obj/O = locate("My Object")

//if O DOES exist...
if(O)
del(O) //delete it so that we can make a new one

O = new
O.tag = "My Object"

var/obj/O2 = locate("My Object")

ASSERT(O == O2) //this should always be true


*edit* Guess that was longer than intended, sorry :x
K looked up locate() and found this.

An optional container object. (The default is world.)

So thanks the default container(list) was world contents. An instance was added to this list with same tag. locate() looked for oldest object with a (Tag.) And that's why ASSERT returned false the second iteration.

edit: Another quote from the reference that supplments: "If there is more than one instance of the specified type, the first one found will be chosen."
In response to Sir Quizalot
Sir Quizalot wrote:
K looked up locate() and found this.

An optional container object. (The default is world.)

So thanks the default container(list) was world contents. The object was added to this list with same tag. When locate() looked for oldest object with a (Tag.) And that's why ASSERT returned false the second iteration.

everyone who has participated in this topic has literally told you this.
Page: 1 2