ID:132383
 
I came across something that I wasn't expecting on load.
The new proc was being called on an entity if it was located inside of a list.
Here is an example
mob
var/obj/book/MyBook
verb
Selftest()
MakeBook()
AddSpellToBook()
Save()
Load()
Save()
var/savefile/A=new("save.txt")
world<<"Saving"
src.Write(A)
world<<"Saved"
Load()
var/savefile/A=new("save.txt")
world<<"Loading"
src.Read(A)
world<<"Loaded"
MakeBook()
MyBook=new()
world<<"Made book"
AddSpellToBook()
if(istype(MyBook))
MyBook.AddSpell()

obj
book
var/list/spells
proc
AddSpell()
spells+= new /spell(1)
world<<"Spell added"
GetSpells()
if(istype(spells))
return "This many spells: [spells.len]"
world<<"No spells"
RemoveSpell()
if(istype(spells)&&spells.len)
spells.len--
world<<"Removed a spell"
world<<"No spells"
spell
New(var/A)
if(!A)
world<<"New was called on load"
del(src)

Is this a bug or is it intended behavior?
Does it call New() while loading on anything other then entity's in lists? I think this should be discussed before a bug report is posted.
Just for the record, this is reproduceable in my game, and it's been holding me up for a few weeks now, although I had never traced the issue back to the New proc, Chowder did, and it seems to be inconsistent, since (according to him) it only happens to objects saved in a list.
This is not a bug. Calling New() is sensible behavior--the object is after all being created. The only real difference is that unlike a vanilla object it has vars filled in.

Lummox JR
I don't quite understand how this is an issue. When you load a mob, the entities inside of any variables are "created" thus calling New().
In response to Lummox JR
It just seemed a bit off to me, because when I thought New() I thought of the first instantiation exclusively.
In response to DivineTraveller
Think of it like the Java Persistence API, or Java RMI, where an object that is deserialised has static iniitalisers called.
In response to Lummox JR
The only problems I have with it is that after Read calls New it overwrites all the variables, which is a little redundant, and that New is also called without the parameters the programmer originally intended it to have. I can work around it now that I know what it does, but it should be documented in the reference.
In response to Duelmaster409
The problem is that entity's that are being "created" are having New called without the intended parameters. Most entities should check there parameters for legitimacy, but in the case of New this is apparently a bad idea because it will delete itself or throw an error.
In response to Chowder
Chowder wrote:
The only problems I have with it is that after Read calls New it overwrites all the variables, which is a little redundant, and that New is also called without the parameters the programmer originally intended it to have. I can work around it now that I know what it does, but it should be documented in the reference.

I don't understand the problem. If you want different behavior, then overwrite Read()/Write() or write your own procedures doing the same thing, in the way you want it done.

In response to Alathon
Let me quote myself...
"I can work around it now that I know what it does, but it should be documented in the reference."
In response to Chowder
Chowder wrote:
Let me quote myself...
"I can work around it now that I know what it does, but it should be documented in the reference."

I think the reference entry is mostly fine, especially coupled with the DM Guide examples. However, I suppose it doesn't explicitly state that it will recursively create objects. But thats a given, since as it says, if it stumbles upon an object stored via Write(), it will create it and call object.Read() on it.
In response to Alathon
http://www.byond.com/members/?command=reference&path=datum/ proc/Read
http://www.byond.com/ members/?command=reference&path=savefile/ operator/%26gt;%26gt;
The closest thing I can find to your "quote" is this:

"If the value read is a previously written object, its own directory will be opened and the object's Read proc will be called to load any data that was written in the object's Write proc."

It does not specify that it creates an object. Nor does it specify it calls New. If it was actually written as

If the value read is not a previously written object, the object will be created with New(), then its own directory will be opened and the object's Read proc will be called to load any data that was written in the object's Write proc.

Then I would agree with you.
In response to Chowder
Chowder wrote:
"If the value read is a previously written object, its own directory will be opened and the object's Read proc will be called to load any data that was written in the object's Write proc."

It does not specify that it creates an object. Nor does it specify it calls New.

In order for any procedure tied to an object to be called, the object must exist. This is a part of the basics of the language.

While the reference is slightly vague in that it doesn't explicitly state that the object is created, it mentions that the objects Read() procedure is called - So it must have been created. The DM Guide further clarifies the specifics of all of this. In any case, if you feel strongly that the reference entry is badly worded, then perhaps leave a comment in the reference explaining the missing information.
In response to Alathon
Alathon wrote:
In any case, if you feel strongly that the reference entry is badly worded, then perhaps leave a comment in the reference explaining the missing information.

Most of us can't do that.
In response to Nickr5
Nickr5 wrote:
Alathon wrote:
In any case, if you feel strongly that the reference entry is badly worded, then perhaps leave a comment in the reference explaining the missing information.

Most of us can't do that.

Oh; I actually wasn't aware of that. I've been away from BYOND for a long time and as such stuff like that escapes me :) My bad.
In response to Chowder
Chowder wrote:
It does not specify that it creates an object. Nor does it specify it calls New.

Forget the specifics of object loading... You know that the object is being loaded. Before the loading, there is no object, and after it, there is one, and you can access it and do stuff with it. What happened in-between...?

To access something, it must first be in existence... so it must be created first. No brainer, right? After an object is created, its New() proc is called (note that it's not New() itself that actually does the creation).
That's what you're experiencing. It is not written that New() "cares" about how and why the object was created -- it's created, so it's called.

I don't feel the reference requires changing, as this is quite simple stuff, as you can see.
In response to Kaioken
It's not about what I know. It's about what others might not know. I would rather have the reference contain the details, then assume people who have never programmed before can infer the specifics of loading.
In response to Chowder
Chowder wrote:
It's not about what I know. It's about what others might not know. I would rather have the reference contain the details, then assume people who have never programmed before can infer the specifics of loading.

The reference is not for people who have never programmed before; it is a language reference. For learning the language, the DM Guide is what you want to read.

Which, coincidentally, contains a long and solid description of all of this.
In response to Alathon
Good one. I admit defeat.