Stonehouse Posted September 23, 2015 Posted September 23, 2015 (edited) Trying to get something straight in my head around returning tables from a function. If I have a script that is like: do tableA = {} local tableB = {} . . function xyz(side) tableA[side] = blah blah tableB[side] = stuff stuff . . return tableA[side] end . . . end Ok few questions and clarifications sought on the statements below: tableA is a global declared table so is freely available throughout the script and also outside in the DCS mission because essentially DCS calls the script and tableA is global. I understand the return passes back a pointer to the portion of tableA for index side and not the actual table data itself. anything incorrect? If the table is global why is a return needed? Wouldn't the changes to the table done in the function be reflected immediately outside? Is there any reason why you would return a pointer to only a portion of the table rather than the whole? eg return tableA rather than return tableA[side] What are the ups and downs and implications of the two tableB is a local declared table so is only freely available within the script. I understand because it is declared in the outer do-end block that it is freely available within function xyz. I believe that any updates to the table within function xyz are reflected outside the function in the script. Do I need to return tableB in order to see the changes? In the sort of logic example above what does the return of the table/s acheive or why is it needed? Thanks, Stonehouse Edited September 23, 2015 by Stonehouse
Grimes Posted September 23, 2015 Posted September 23, 2015 Trying to get something straight in my head around returning tables from a function. Ok few questions and clarifications sought on the statements below: tableA is a global declared table so is freely available throughout the script and also outside in the DCS mission because essentially DCS calls the script and tableA is global. I understand the return passes back a pointer to the portion of tableA for index side and not the actual table data itself. anything incorrect? Correct If the table is global why is a return needed? Return isn't necessarily needed, but it is usually a good habit sort of thing. You can always just type "return" without actually telling it to return anything. Wouldn't the changes to the table done in the function be reflected immediately outside? Yes. Is there any reason why you would return a pointer to only a portion of the table rather than the whole? eg return tableA rather than return tableA[side] Sure, say you are working with another coalition wide function where only the sides data matters. You could just make a new table with either main table or a returned table local sideCoa1 = tableA[side] local sideCoa2 = xyz(side) They should both be the same thing. If you don't need to see the blue side of the table you don't need access to it. Plus it might make things easier in not having to specify which side of the table you are working with anytime you want to change a value. What are the ups and downs and implications of the two The short of it is local variables are ALWAYS faster than global. This is true even for a "local of a local" variable. What I mean is that local variables declared within a function are faster than a local variable grabbed from outside the function which the function still has access to. You can make a local reference of more globally accessible values and it will run much faster if its doing a lot of work. It only makes sense to make a local version of a table or a function. A single value like string, boolean, or number won't see much of a performance impact. For example mist has a function to update all alive units and their positions for the DB mist.DBs.aliveUnits. Within the function it creates a local reference of mistDBs, functions and even the Unit class created by DCS. local lalive_units = mist.DBs.aliveUnits -- local references for faster execution local lunits = mist.DBs.unitsByNum local ldeepcopy = mist.utils.deepCopy local lUnit = Unit local lremovedAliveUnits = mist.DBs.removedAliveUnits A good rule should be that only what is required to be global should be global. But even then its not actually required for it to be global. By that I mean you can have a global function that has access to local values to use said values in a separate script. My IADS script works like this, the actual table containing all of the iads information is local within the script, but the function iads.getByName() is a global function that has access to the iads. My iadscript wasn't initially like this, it was a change I had to make for performance reasons. tableB is a local declared table so is only freely available within the script. I understand because it is declared in the outer do-end block that it is freely available within function xyz. I believe that any updates to the table within function xyz are reflected outside the function in the script. Do I need to return tableB in order to see the changes? In the sort of logic example above what does the return of the table/s acheive or why is it needed? Again you shouldn't have to, its just a question of how you are using the function. Changes should be instance, but it really depends on how you might be updating the table. AFAIK if you are iterating it and using the following changes won't be made to the table. for i, data in pairs(tableB[side]) do data.whatever = false end The right man in the wrong place makes all the difference in the world. Current Projects: Grayflag Server, Scripting Wiki Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread) SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum
Stonehouse Posted September 23, 2015 Author Posted September 23, 2015 (edited) Ok thanks as always Grimes. Some of that will take a bit of digesting and possibly generate some more questions but I am glad that generally I seem to be heading in the right direction. On the tableA[side] and tableA thing I get the impression from your response re: sideCoa1 and sideCoa2 that again it is only pointers? so if you make changes to the table referred to by sideCoa1 say it will also be reflected in table referred to by tableA? or am I getting off the track? I suppose just for completeness sake - if instead of tables I had two variables but still declared as a global and a local to the script so I believe the scope is the same - does that change anything about your comment of not needing to return the variables from the function? If so, is the return statement in some ways just a commentary or descriptive thing to make it easier to see what the function is meant to do? or is it actually required in certain circumstances? You may have already covered this in your reply but it hasn't sunk in yet so if so apologies and just tell me that's the case. Cheers, Stonehouse Edited September 23, 2015 by Stonehouse
Grimes Posted September 23, 2015 Posted September 23, 2015 Yeah its a reference (or pointer whatever) of that variable. Its not a separate copy. What you do to one will change on the other. But its a good habit to only mess with the local version. The right man in the wrong place makes all the difference in the world. Current Projects: Grayflag Server, Scripting Wiki Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread) SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum
Recommended Posts