Declare Most Object Variables As An Array Of Length 1?

Long time lurker, first time thread creator.

I ask this with great hesitation because it sounds so stupid, but I've been wondering about this for a while and the core question I have is:

Is there any disadvantage to declaring all or most object/instance variables as an array of length 1?

example:
Code:
myHealth[0] = 100;
Oddly, googling "every variable an array" only turns up one relevant result of somebody making fun of the concept on the entire web of people asking CS questions, and I couldn't find anything in the forums about it, so, apologies if it's been covered. But I'm aware that obviously each language can treat this scenario differently too.


The reason I'm asking is for something like the following scenario:

Let's say an object is going to display a string in an RPG text window, and it wants the string to look "typed out". You obviously could implement this in lots of ways, but let's say I want to pass variables by reference and execute it in a more elegant way like:

Code:
inputString[0] = "Greetings";
outputString[0] = "";
typingTime[0] = 100000;  // Micros per character
outputStringCompleted[0] = false;
scr_typewriter(id,inputString,outputString,typingTime[0],outputStringCompleted);

(note that I chose to pass "typingTime" by value instead of reference so I could use a literal in the original call, which is easy to indicate on the fly, and id is passed by value by default)

and just have "scr_typewriter()" in my personal library of functions, where internally it would look kind of like:

Code:
///@arg callingObjectID
///@arg ptr_inputString
/// etc, to inform in the function description which variables
///are supposed to be addresses instead of values.

var typingObject = instance_create_depth(0,0,0,obj_typewriter);
typingObject.callingObjectID = argument[0];
typingObject.ptr_inputString = argument[1];
typingObject.ptr_outputString = argument[2];
typingObject.typingTime = argument[3];
typingObject.ptr_outputStringCompleted = argument[4];


and in the step function of obj_typewriter:


Code:
if (instance_exists(callingObjectID)) {
    ptr_outputString[@0] = string_copy(ptr_inputString[@0],1,increasingPosition);
    accumulatedDeltaTime += delta_time;
    if (accumulatedDeltaTime > typingTime) {
        accumulatedDeltaTime -= typingTime;
        increasingPosition++;
        if (increasingPosition > string_length(ptr_inputString[@0]) {
            ptr_outputStringCompleted[@0] = true;
            instance_destroy();
        }
    }
}
else {
    instance_destroy();
}

This is sort of meant as pseudocode, so please excuse any logic or syntax errors, but hopefully I've conveyed the concept of being able to simply just call scr_typewriter() at any time in any future project without any additional coding. Obviously, there are a lot more concepts that this could extend to.

You could make the argument that I could just declare specific variables as one position arrays, but i'd have to go back and rename things on the fly whenever I realize I want to pass them by reference, which is a lot of extra work and raises the possibilities of creating bugs.

I could also pass the instance id of the calling object by value to obj_type, and strings of the variable names I want it to access on that instance, but because of the string lookup, that sounds like a huge performance hit if used repeatedly for non-object-creating scenarios.

So, what possible cons am I not thinking of? Access time? Memory fragmentation and segmentation errors? (Does GMS2 just allocate space for one variable if you only ever use an indexer of 0?) Garbage collection? Specific scenarios where I can't use an array position? GMS2 will give a compiler error if I accidentally try to perform any operation on an array without an indexer, correct? All you can ever do with the array name itself is pass the address of the array to a function, right?

Happy to hear if this is a super dumb idea!
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
This is called boxing and it's a pretty commonly used concept.

Access time or caching may be affected as instead of having the variable "slot" reference it's value directly you have it reference an array container which holds length and a pointer to the first element which is where the value is, but I don't imagine that you would be using in extremely-performance-critical contexts. Even then, you could simply copy the value to a local variable during intensive use and then assign it back.
 
Wow! Thank you for reading all that and giving such an awesome response! And thank you for the link! I also checked out your blog and what you've written about this and a lot of other OOP implementations. Thanks so much for writing about all of that so extensively. I feel like I'm going to have to rethink the entire way I use GML haha.
 
Top