What is the behaviour when you set a variable to another variable? I am using Sugarcube 2.
Say I have $array which is an array of characters and I go:
<<set $array[0].name to "foo">>
<<set $char to $array[0]>>
<<set $char.name to "bar">>
Will &array[0].name now be foo or bar? It seems to be very inconsistent, with the value sometimes retroactively updating and sometimes not. Is there some update mechanism which triggers in specific situations?
Thanks!
Comments
What happens when you update an attribute of the referenced object depends if that update is done in the same navigable passage as the object reference assignment or not.
1. Attribute update is done is same navigable passage as the object reference assignment:
Because both variables are reference the same object then the update effects both.
2. Attribute update is not done is same navigable passage as the object reference assignment:
Each time the reader navigates (forward) between passages a copy of all known variables is created and it is that copy which is made available to the next passage, this is done so that the History system can undo the navigation.
This copying process results in variables that were referencing the same object to now each be referencing their own copy of the original object.
2a. First passage:
2b. Second passage:
So char and array[0] are in fact identical pointers. However, when I move between passages, Twine does
And it's this charNew and arrayNew that is used in the new passage, so now they're pointing to distinct objects, copies of what they originally referenced.
Is that sort of what you meant, as far as end user functionality is concerned?
Yes.
I used a less technical explanation because there is no way of knowing the technical level of the person asking a question, nor of the others that may read this topic later. *smile*
And the explanation was very clear, I just wanted to double check. Much appreciated!
Before I mark this as closed, does this behaviour only apply to objects, or to all variables such as numbers/strings? Also, is there any way to create a 'true' copy of an object within the same passage? That would be very convenient in some cases
Thanks!
Use the SugarCube clone() function.
Value types have pass-by-copy semantics and are primitives like: numbers (incl. both integer and floating-point), strings, booleans, symbols, and the two special values: null and undefined.
Reference types have pass-by-reference semantics and are objects. In JavaScript, every data type which is not a value/primitive type is an object at heart—this includes arrays and functions/methods.
Suggested reading (from the Mozilla Developer Network (MDN)):
FYI. Each value/primitive type, save for null and undefined, also have an associated object, which is where the types' methods are stored. For example: numbers have Number, strings have String, and so on. Do not confuse the value type with its associated object. Also, as a general rule, never use the constructor for the associated object of a value type as a constructor—calling it with the new keyword—to create a new instance of the type—use its literal notation instead. For example: That said you may call the constructor for the associated object of a value type without the new keyword—basically calling it as a simple function, rather than as a constructor—to do type conversions. You probably won't do this very often, as implicit type coercion is a thing and there are other ways to do explicit type conversions, however, it can occasionally be useful. For example:
As greyelf mentioned, the clone() function, which returns a deep copy of the original. Be sure to read its documentation to learn of its limitations—it does not support every native object type that JavaScript offers.
I may be blind, but I can't find the button to mark thread as answered. If this is an mod only thing please go ahead, if not please point me the right way