When a global variable is justified

33 visualizzazioni (ultimi 30 giorni)
Valtar
Valtar il 4 Lug 2023
Commentato: Jan Kappen il 4 Set 2024
I use few global vars in my app. The Code Analyzer suggests to get rid of them, but this would involve--in my view--more complicated coding. I'd like to learn the best programming practice in this regard and maybe a fix is simpler than I think.
I use global vars for two main reasons.
First, I need a debug flag in all my functions. This is to spit out debug info if app is run with a debug flag (on the command line). To fix this, I would need to intorduce an additional input variable in all definitions and calls. To me, this is more ugly compared to a line of global definition inside each function. But in general this is easy to fix (introducing addional input argument).
Second, this is more difficult, I think. One function logit() writes log info in both GUI text box and in the file on disk. Thus, it needs FID of the file, and a text box handler, plus another flag which tells if the app runs in batch mode (w/o GUI) or not. For the latter, probably there is a way to find out batch or not via a GUI ask, as well as it shall be possible to find the text box handler via a GUI ask, i.e. w/o explicit handler in a varable. So, I guess it is possible to fix my logit(), where it would have more logic to find out: batch or not, find the needed handler for the text box, and have the file FID in a persistent local variable, maybe (if other funcs do not write to this file).
Thanks
  5 Commenti
Valtar
Valtar il 4 Lug 2023
@Stephen23, I think I have confused all by using "app" as equivalent to "software" ;) My software (eventually a compiled Matlab porgram) is runing in batch mode (w/o GUI) as well as in GUI mode. And if i can work on logit() internal logic to be able to find which mode I'm runing and then query for the text box handle, the issue with the debug flag stays. I struggle to understand the need to refactor it as an additonal input variable :) it's very benign. if something wrong happens to it, nobody will get hurt)
Stephen23
Stephen23 il 4 Lug 2023
" if something wrong happens to it, nobody will get hurt"
The important question is: if something goes wrong with the global, can it in any way (silently) affect the data being processed? If yes, then using globals is a risk. Otherwise... you could consider the global benign.

Accedi per commentare.

Risposte (3)

Matt J
Matt J il 4 Lug 2023
Modificato: Matt J il 4 Lug 2023
To fix this, I would need to intorduce an additional input variable in all definitions and calls.
No, you could add the debug flag as an app property. Then, it would get passed around to all the callbacks and class methods as part of the app object that gets passed to them automatically.
  9 Commenti
Valtar
Valtar il 4 Lug 2023
Only the GUI callbacks are nested. All the processing functions are not. And I need logit() all other the software; eveywhere instead of fprintf().
I have just realized that if I eliminate GUI related globals in logit(), and instead will search for the needed handle with findobj(gcf,....), then it could be slower than the global var... I can propably store the needed handle in guidata, and in logit() just check if guidata exists (meaning that the SW is in GUI mode), and if yes, just grab the needed for the output handle.
Matt J
Matt J il 4 Lug 2023
Modificato: Matt J il 4 Lug 2023
You can make wrapper for logit which will use the externally scoped variables. You can use the wrapper within your GUI as a local, specialized version of the general function.
function guiMain
debugFlag=true;
...
function logitLocal(varargin) %wrapper
if debugFlag
logit(something)
else
logit(something_else)
end
end
end

Accedi per commentare.


Image Analyst
Image Analyst il 4 Lug 2023
@Valtar by not using app designer because you think it gives you better control, well, I take issue with that. I'd like to see some example of that. But by doing all the tedious things of setting up callbacks, etc., I think you're actually creating more work for yourself, or you just end up with a simple, more basic app than you could otherwise if you'd have used App Designer.
Globals create variables in the global workspace, which can stay there until you shutdown MATLAB or call "clear globals". This can cause problems if you end up using global variables with old, no longer appropriate, values in your new runs. With app designer the globals are all internal and don't live beyond the running of your app.
However you get the effect of globals with app designer by creating and using a property of the app object. Any function in there can automatically see app.varName (or whatever you call it) without you having to explicitly say "global varName" inside every function that needs to use that variable.

Jan Kappen
Jan Kappen il 3 Set 2024
What about a global logger class? You set select the log-levels at creation time.
  4 Commenti
Rik
Rik il 4 Set 2024
Ah, I thought you meant people could use a global to store an instance of a logger class, not that an instance of a logger class could replace the use of a global.

Accedi per commentare.

Categorie

Scopri di più su Performance and Memory in Help Center e File Exchange

Tag

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by