Forcing+a+variable+to+exist

//by Richard Russell, May 2006//

Programs frequently need to contain a //cleanup// routine which gets called before the program quits. Such a routine may close files, remove open dialogue boxes, free Windows resources that have been allocated (e.g. memory or graphics objects) etc. So the routine will typically include code similar to the following:

code format="bb4w" DEF PROCcleanup CLOSE #Outfile% PROC_closedialog(Dialogue%) SYS "GlobalFree", Memory% ENDPROC code The cleanup code will need to be executed not only on the normal exit from the program but also if a premature exit takes place because of an error (including Escape) or the user clicking on the **Close** button. Therefore it is likely that the routine will be called from both **ON ERROR ** and **ON CLOSE** statements:

code format="bb4w" ON CLOSE PROCcleanup : QUIT ON ERROR SYS "MessageBox", @hwnd%, REPORT$, 0, 48 : PROCcleanup : QUIT code But this immediately causes a problem. What happens if the premature exit occurs //before// one or more of the variables used in **PROCcleanup** have been created? The result would be a **No such variable** error, which would activate the ON ERROR routine, which would call PROCcleanup, which would result in another error and so on //ad infinitum//. This is not good!

What is needed is a way of forcing a variable to exist if it doesn't already, but leaving its value unchanged if it does. Fortunately **BBC BASIC** provides two ways of doing this:

code format="bb4w" variable = variable variable += 0 code Both these have the same effect: if **variable** already exists it is left unaltered, if **variable** doesn't exist it is created and its value is set to zero. Obviously there are a number of other equivalent operations such as but the two listed are the ones most commonly used.

So armed with this knowledge we can now modify **PROCcleanup** so that it never fails with a **No such variable** error:

code format="bb4w" DEF PROCcleanup Outfile% += 0 : IF Outfile%<>0  CLOSE #Outfile% Dialogue% += 0 : IF Dialogue%<>0 PROC_closedialog(Dialogue%) Memory% += 0  : IF Memory%<>0   SYS "GlobalFree", Memory% ENDPROC code Of course this relies on the normal values of the variables never being zero, but in general that is the case.

You can use this technique whenever you can't be sure whether a variable has been created or not.

//Added by JGH, May 2006//

This can be improved a little. What would happen if **PROCcleanup** was called again? If **Outfile%** was still nonzero, it would attempt to close a channel that has already been closed. After the cleanup operation the variable should be set to zero, eg **CLOSE#Outfile%:Outfile%=0**.

If **PROCcleanup** is called by ON ERROR, what happens if the cleanup causes an error? It is called again. If, for example, **CLOSE#Outfile%** causes an error, **PROCcleanup** will be called again, which will then try to do **CLOSE#Outfile%** again, which will cause an error...

What I prefer to do is zero the variable before doing the cleanup, which means if the cleanup is called again an invalid cleanup isn't attempted.

code format="bb4w" DEF PROCcleanup LOCAL temp% Outfile% += 0 :IF Outfile% :temp%=Outfile% :Outfile%=0 :CLOSE #temp% Dialogue% += 0 :IF Dialogue%:temp%=Dialogue%:Dialogue%=0:PROC_closedialog(temp%) Memory% += 0  :IF Memory%  :temp%=Memory%  :Memory%=0  :SYS "GlobalFree", temp% ENDPROC code This is the technique I use in my BASIC program libraries, such as the Close library.