ID:104865
 
Not a bug
BYOND Version:469.1073
Operating System:Windows Vista Home Premium
Web Browser:Firefox 3.6.3
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:

We can no longer create new instances of objects in an object's field-initialization. If you try, the project will compile fine, but, at runtime, this produces bizarre errors when you try to use the field where the object does not exist yet is not null either. If you compare the object to null, the comparison fails, and if you check to see if the field is false, that comparison also fails [if(field == null) and if(!field)].

The only way I've noticed so far in which I can use the field and not get a runtime error is if the field is a /list and I try to iterate over it with for(var/x in list), which does not throw a runtime error but still does not iterate at all (as if it's an empty list)

Numbered Steps to Reproduce Problem:

1) Initialize an object's field to a new instance of an object.
2) Attempt to use the field.
3) At the moment it attempts to use the field in some way, the outcome is not as expected; if just outputting the field, it produces a bad output runtime error, if attempting to use one of the field's own fields (since it's supposed to be an instance of an object), it produces a cannot access ".fieldname" runtime error (notice it is not "null.fieldname")

Code Snippet (if applicable) to Reproduce Problem:
mob/var/obj/O = new
mob/verb/v()
src << O // bad output
// or...
src << O.name // cannot access .name

or
mob/var/list/L = list(new /obj)
mob/verb/v()
for(var/x in L)
src << x
// the above loop compiles fine but displays nothing, as if it's an empty list or not a list
src << L.len // cannot display .len

Also note that using newlist(/obj) produces same results

and for completeness...
mob/var/obj/O = new
mob/verb/v()
if(O == null)
src << "O == null"
if(!O)
src << "!O"
// at this point, you have seen no output
// both above expressions resulted in false


Expected Results:

We used to be able to initialize fields to new instances of objects, and it would work fine, as expected. I don't know if seeker/daemon were programmed to create the objects just before world/New() or what, but I recall it used to work.

Also expected: If we're NOT supposed to be able to do this, then it should not compile fine and produce very odd runtime results.

Actual Results:

Runtime errors (explained above) when accessing the field.
Iterating over the field as if it's a list does not produce runtime errors but does treat it as an empty list or not a list.

The object does not seem to exist (the field does not reference anything useful), yet it's not null.

The code compiles fine yet produces these results.

Does the problem occur:
Every time? Or how often?
Every time
In other games?
Probably
In other user accounts?
I was using guest, but no reason for it to be different
On other computers?
Unknown; I have access to only 1 computer at the moment

When does the problem NOT occur?

The problem is always occurring for me. I cannot get it to work as it should (used to).

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? (Visit http://www.byond.com/download/build to download old versions for testing.)

It used to work for me in all previous versions that I would do this in. I update seldom, so I don't recall what the last version was that I used. If I am able, I will test this later and update this entry.

Workarounds:

Create the object as a statement within a function.
I tested all three examples you posted and all of them produced the correct output in version 479. Normally I'd chalk a report like this up as Unverified but it's clear there is some other issue in your project causing the problem. Whether it's something like an intervening save and load, or something else, I'm not sure, but it's definitely a code problem and not a bug.

Your third example is direct proof that something else is wrong, because O is obviously null there and the failure to produce output means either output is being sent to the wrong place (or there's nowhere to send it), or somehow src itself has gotten botched in the routine you're testing. I'm guessing the examples you posted are extrapolated from other code in your project, but were not tested themselves in a vanilla project.
No, all the examples were done in a test environment wherein that was the only code that existed.

Failure to produce output in the third example is because the statements evaluate to false, not because output is being directed to the wrong place. Any other output shows fine. If you were to put in a src << "test" as the first line in that function, you would see the "test" output.

None of the issues stem from anything else interfering.

Either way, if it all displays correctly for you, then that must mean that there was a bug that worked itself out somewhere between then and the new version.
Huh, I misread the version you reported because the current one is 479 and the one you listed was 469. It's possible that explains it. However none of this behavior was ever changed to my knowledge so I really think some kind of instability on your end is still the culprit. I mean the third example simply can't happen--if you don't specify an initial value for O, it's definitely null. The fact that your test failed even there says something much worse is wrong.

469 is so far out of date though that there is no point reporting bugs in it, unless your report includes info that newer versions show the same issue. It's always best to upgrade first to see if the bug has already been taken care of.
Lummox JR wrote:
I mean the third example simply can't happen...

It doesn't really matter since it's not a bug anymore, but I just felt the need to clarify this one thing.

I don't know how the heck it happened, but in my original test code that was "var/obj/O = new" not just "var/obj/O" I must have made some kind of mistake in transferring it over.

Again, doesn't matter anymore, but I just wanted to clear that up for completeness. And I will edit the original report to reflect this.
Ah, that explains much then. That would indeed be possible if the first two cases were possible. From the code as it was posted it looked like you were intentionally initializing to null and then showing that the output wasn't produced even when testing for null.