use of global variables
24 views (last 30 days)
%I have a question about how to use global variables within functions if you are calling other functions within a function; I think I have done it correctly but I am a little unsure: If I have declared some variales as global at top of a function, can these be computed as being output from other functions called within the function I have declared these variables within as this:%
function [best_salt_1, best_salt_2]=dropdown_best_2_salts()
global maks_vektprosent_lost_nacl maks_vektprosent_lost_CaCl2 maks_vektprosent_lost_KCl maks_vektprosent_lost_ZnSO4 maks_vektprosent_lost_MgCl2 maks_vektprosent_lost_kaliumacetat maks_vektprosent_lost_natrium_format maks_vektprosent_lost_kalium_format maks_vektprosent_lost_NH4Cl maks_vektprosent_lost_zinkbromid maks_vektprosent_lost_CaBr2
[~,maks_vektprosent_lost_CaCl2,~,~,maks_vektprosent_lost_MgCl2,~,~,~, maks_vektprosent_lost_NH4Cl,~,~]= beregn_maks_vektprosent_lost (forste_saltet, andre_saltet, tredje_saltet);
% Similarly I have declared the same variables as global variables in another function that is sending those variables as input to another function called within that function:
function [vannaktivitet_best_salt_1, vann_aktivitet_best_salt_2, samlet_vannaktivitet]=beregn_aktivitet(best_salt_1, best_salt_2)
% Can global variables be used in this way?
Jan on 29 Nov 2021
Edited: Jan on 29 Nov 2021
I agree with John, Rik and Stephen, and dare to post this as an answer.
Can global variables be used in this way? Maybe. The access of global variables is deterministic. After declaring a variable as global, you can read and write to in.
This makes it very hard to debug your code, because the source of the last change of a variable cannot be determined directly. This problem concerns all programming languages and many professional programmer avoid global variables strictly.
You code contains another anti-pattern:
~,~,~, maks_vektprosent_lost_NH4Cl,~,~] = beregn_maks_vektprosent_lost( ...
forste_saltet, andre_saltet, tredje_saltet);
This looks, like the names of the variables contain important information in low level function. This happens, if you write some code, which works for one specific problem only. A gegenral method in programming is to write more abstract codes. This has the advantage, that the code can be re-used for other problems and it can be tested with different cases to validate, that it is working at all.
The strict separation of data, code for processing and GUIs are a smart concept for improving the code quality.
Take a look into the code of e.g. ODE45. Here the state variable is y and the independent variable is t. You can integrate all non-stiff ODEs with this scheme and it does not matter if the inputs are Dollars, bananas, concentrations or meters. t need not be the time. The integrator can be tested exhaustively and is a powerful tool.
Check you code again and think about a more abstract version. Then only the main program knows, that NH4Cl is concerned, while the subroutines work with numbers (which might be concentrations) only. Providing a set of numbers to a subfunction is done by an array, which is easy, clear and compact. This reduces the need to use a bunch of global variables with long and confusing names. And it avoid the cruel effect of typos as in:
maks_vektprosent_lost_kaliumacetat = 0;
x = 1;
y = theSub(x)
function y = theSub(x)
maks_vectprosent_lost_kaliumacetat = maks_vectprosent_ost_kaliumacetat + 2;
y = x + 1;
Here the value of the global variable of the main program is not modified in the subfunction due to the typo 'c' instead of 'k'. With using Matlab auto-completion this happens fast and the debugging is extremely hard, if the code has 100'000 lines.
The good programming practice is, that typos have local effects only and do not influence other parts of the code, which are several level away.
Avoid global variable and provide the data as inputs and outputs:
vektprosent_lost_kaliumacetat = 0;
x = 1;
[y, vektprosent_lost_kaliumacetat] = theSub(x, vektprosent_lost_kaliumacetat);
function [y, c] = theSub(x, c)
c = c + 2;
y = x + 1;
Now typos in theSub have local effects only and it is much easier to find problems.