Accessors

Aegri

Member
I read the manual page on accessors. From what I at first understand is that they are shorthand ways to type the get functions.

GML:
mv = amap[? "keyword"]; <=> mv= ds_map_get(amap, "keyword);
lv= alist[| 5]; <=> lv= ds_list_find_value(alist, 5);
gv =agrid[# 3, 4]; <=> gv= ds_grid_get(agrid, 3, 4);
Now I'm far from the brightest light and not the best at text comprehension when reading things the first, second, thrid time.

So I read the accessor page again and again and it dawned on me they are likely also shorthand ways to type the set functions.

GML:
amap[? "keyword"]=1; <=> mv= ds_map_set(amap, "keyword",1);
alist[| 5]=1; <=> ds_list_instert(alist, 5,1);
ag[B]rid[# 3, 4] =1; <=> ds_grid_set(agrid, 3, 4)=1;
Overall if this is correct that is nice to know.


Just my wish is that the manual page or information on accessors be less shy and place a link on related manual pages.
 
You forgot the struct accessor $, like:
GML:
my_struct[$ "my_struct_variable_as_a_string"] = true;
But yeah, they are pretty much just shorthand, because we are so very lazy at typing.

You can use them to set and get values as well, as you mentionned. Just depends on how you use it.
GML:
var my_flag = my_struct[$ "my_struct_variable_as_a_string"];
 

Aegri

Member
Okay thanks for the reply.


Something that I notice with structures is that delete can only be used outside if structure code.
That is okay.

However what if I place an array, a map, a grid or a list in a structure, is that going to be co-deleted when a structure is deleted?

Or do I have to delete above manually before deleting the structure?

And if latter is the case - and me being aware of the concept of garbage collectors - does that sort of point to a way of introducing memory leaks?
 

TsukaYuriko

☄️
Forum Staff
Moderator
It depends.

Arrays and structs are reference-counted. If nothing references them, they will be garbage collected eventually (not instantly).
Data structures (ds_*) are not reference-counted. If you delete a struct that holds the only reference (really just a numeric ID) to a data structure, you just caused a memory leak. These need to be manually destroyed using the appropriate functions.
Likewise, if the only place you store a list's ID is inside of another list and you then delete that list, you just caused a memory leak as you now have no way to know that inner list's ID anymore.


To summarize: If you exclusively use arrays and structs, everything is garbage collected. These two can replicate the functionality of all the ds_* data structures.


Let's also not forget about the array accessor. I can probably imagine your confusion about this one, as it isn't much of a shorthand because... well, accessing arrays normally is shorter? That's because there's a functional difference between using it and not using it, and that is the point of its existence.

Normally, arrays follow a copy-on-write behavior. This means that, when you assign the same array to two things, all you're really passing around is a reference, not the array itself.
When you write to one of these referenced arrays, however, the two things will no longer reference the same array. Rather, the one that overwrote something has now created a copy of the array.
If this is not what you want, you have to use the array accessor when writing to an array. This will override the copy-on-write behavior and ensure that you always write to the referenced array rather than copying it.
 
Last edited:

Aegri

Member
Let's also not forget about the array accessor. I can probably imagine your confusion about this one, as it isn't much of a shorthand because... well, accessing arrays normally is shorter? That's because there's a functional difference between using it and not using it, and that is the point of its existence.

Normally, arrays follow a copy-on-write behavior. This means that, when you assign the same array to two things, all you're really passing around is a reference, not the array itself.
When you write to one of these referenced arrays, however, the two things will no longer reference the same array. Rather, the one that overwrote something has now created a copy of the array.
If this is not what you want, you have to use the array accessor when writing to an array. This will override the copy-on-write behavior and ensure that you always write to the referenced array rather than copying it.
So to rephrase that in gml

GML:
a[0]1

some_function(a){
a[0]+=1 //is a new array a with value 2
}

var _val=a[0] //old array and _val= 1
while

GML:
a[0]1

some_function(a){
a[@ 0]+=1 //is old array a having value 2
}

var _val=a[0] // _val=2
Okay thanks I keep that in mind.
 
Top