[WIP][General Information] Value vs Reference Types, and arrays

This forum serves as MSCI Reference at EGOSOFT. It's Read-Only for non MSCI Group members.

Moderators: Scripting / Modding Moderators, MSCI Moderators

Post Reply
User avatar
Posts: 2011
Joined: Wed, 29. Jun 05, 01:45

[WIP][General Information] Value vs Reference Types, and arrays

Post by s9ilent » Wed, 6. Oct 10, 12:36

All variables can be grouped into one of two categories


Value variable - A variable which holds an actual piece of information (e.g. an integer)
Reference variable - A variable which only holds a reference to a piece of information (like a hyperlink~) e.g. In game Ships/stations, arrays, read texts

Value variables are the easiest to understand. e.g. Integers
$i = 1
$i has a value of 1
$i = $i + 1
$i has a value of 2

Reference variables, are a bit more complicated. The simplest example of a reference variable, is a variable that references an in-game ship.
A ship, is made up of many pieces of information (e.g. shields, hulls, wares, sector, xyz, abg, turrets, weapon, model etc.) When ever you have a variable that holds a ship, it does not duplicate all this information into your variable, what it does, is it provides a reference (or a link) to the ship.
$ship = [PLAYERSHIP]
$ship does not actually hold the information of the ship, it provides a link to the ship.

Similarly, if I did
$ship1 = [PLAYERSHIP]
$ship2 = [PLAYERSHIP]
$ship3 = [PLAYERSHIP]
All 3 of these ships reference the same ship. So changing any one of the ships, will show the change in the others (as they are referencing the same ship)
$ship1 -> set speed to 42
$speed1 -> $ship1 get current speed
$speed2 -> $ship2 get current speed
$speed3 -> $ship3 get current speed
$speed4 -> [PLAYERSHIP] get current speed
All of the speed1-4 are now all equal to 42

Arrays (Reference Variables) (Single Dimension)

Things become rather complicated when you are using arrays as they are reference variables too.

$arrayOriginal -> array: allocsize = 5
$arrayOriginal[0] = 'a'
$arrayOriginal[1] = 'b'
$arrayOriginal[2] = 'c'
$arrayOriginal[3] = 'd'
$arrayOriginal[4] = 'e'
Result: $arrayOriginal = { 'a', 'b', 'c', 'd', 'e' }

$array1 = $arrayOriginal
Result: $array1 = { 'a', 'b', 'c', 'd', 'e' }

Now, here is where the tricky part begins
$arrayOriginal and $array1 are actually referencing (i.e. hyper linking to) the exact same array
So if I modify 'one' of the arrays, it will show the change in the other
$arrayOriginal[4] = 'I am not e!!!'
$arrayOriginal = { 'a', 'b', 'c', 'd', 'I am not e!!!' }
$array1 = { 'a', 'b', 'c', 'd', 'I am not e!!!' }

Much like the example with the Playership's speed, changing 'one', shows in all of the references. (this is because they are both referencing the SAME array, in much the same way we where previously referencing the same PLAYERSHIP)

I have put quotes around the word 'one', as saying that might imply that there are two arrays, but there is only ever 1 array in all that code

Nested Arrays (Multi Dimensional arrays)

A nested array, or multi dimensional array, is just an array of arrays, so you must show extra care when using them.

$nestedArray = array: alloc size = 100
$subArray0 = array: alloc size = 10
$subArray[0] = 42

$variableArray = $nestedArray[0]
$variable42 = $variable1[0]

<----I am now here in my code

So at this point, $variable42 now holds the VALUE 42
It does NOT hold a reference to $variable1[0] nor does it hold a reference to any of the arrays. So changing $variable42 , does NOT change the arrays, and nor does the changing the arrays affect $variable42

HOWEVER, $variable1 holds the VALUE $nestedArray[0], but the value, is a reference to the array $subArray0. So in truth, it holds a REFERENCE to $subArray0
Meaning that if you change $subArray0, you will see those changes in $varaible1

Cloned Nested Arrays

Lets say I have a 10x10 square multi dimension arrays with
$squareMatrix[$i][$j] = 10 * $i + j
e.g. $squareMatrix[4][2] = 42

Now if I clone my square matrix
$clone = clone array $squareMatrix : index 0.. 9
My clone matrix, is now also a 0-99 square. HOWEVER, as it is a clone, it is a DIFFERENT array
Fact: $squareMatrix != $clone
HOWEVER, the clone instruction only creates a shallow clone (i.e. it does not iterate the cloning process into the subarrays)

So even thou $squareMatrix != $clone
Fact: $squareMatrix[$i] == $clone[$i]
i.e. $clone row1 is the SAME array as $squareMatrix row1

This can lead to interesting outcomes
Example 1:
$var1 = $clone[4][2]
$var2 = $squareMatrix[4][2]

$var1 = 42
$var2 = 42

Example 2:
If I null the top row on one, but no the other

$clone[0] = null
$var1a = $clone[0]
$var1b = $clone[0][4]
$var2a = $squareMatrix[0]
$var2b = $squareMatrix[0][4]

$var1a = null
$var1b = null
$var2a = array {0,1,2,3,4,5,6,7,8,9}
$var2b = 4

Technically evaluating $var1b = $clone[0][4] results in an error, and on error, x3 returns null (for this operation)
As $var1b = $clone[0][4] is identical to doing
$temp = $clone[0] (Result :null)
$var1b = $temp[4] ( null[4] -> ????? error, so Result: null)

ReadText (Reference Variable)

Read Texts, are also another special case of a reference variable.
Whilst you may believe, that a ReadText instruction returns a string, it in fact returns a reference to that particular text file { pageid, textid }.
So if a textfile changes, and you reload it, the referenced string from a ReadText instruction will have changed.

e.g. If I have a Textfile: 7743-L044.xml
On PageId=1, TextId=1, it has the string value='I am the original string'
So if I go
loadtext: id=7743
$myTextReference = readtext: pageid=1, textid=1
If I print $myTextReference to the log book, it will say 'I am the original string'

Now Suppose I hold onto $myTextReference, e.g. If I put it in a menu, global variable, hold it in my script loop (it doesn't really matter how). Then I modify my TextFile (e.g. With an external application) to say:
On PageId=1, TextId=1, it has the string value='I am the NEW string'
So if I go

Then I reload the textfile
loadtext: id=7743
And I get $myTextReference (from my global var/ what ever) with OUT using another readtext
If I print $myTextReference to the log book, it will say 'I am the NEW string'

If this is undesirable to you, then force the textReference into a string, by doing something like $string = sprintf '%s' $myTextReference null null null null, or $string = $myTextReference + '', or pretty much anything with a $variable = $myTextReference + some other operation/some function

I have not tested this with separate textfiles. But I can guarantee it does happen if you change a reference within the same textfile and reload it.
Last edited by s9ilent on Thu, 7. Oct 10, 00:45, edited 2 times in total.

User avatar
Posts: 1958
Joined: Tue, 8. Jan 08, 19:19

Post by ScRaT_GER » Wed, 6. Oct 10, 13:54

(In c#/.Net, the terminology used is reference/value type, but to not get this article confused with data types, I will refer to everything as reference/value VARIABLES)
I think you can safely omit this comment. ;)
Cloned Nested Arrays
Should we really have that information twice in the reference?

Apart from that, everything is fine.


User avatar
Posts: 2011
Joined: Wed, 29. Jun 05, 01:45

Post by s9ilent » Thu, 7. Oct 10, 00:48

I think it would be beneficial to have it in both threads, as the information is a continuation on the explanation of arrays (so it does have relevance here). (And similarly for the read text)

Post Reply

Return to “MSCI Reference”