Forcing a variable to exist

From BeebWiki
Jump to: navigation, search

Programs frequently need to claim some resource, such as an open file or an area of memory, and need to be able ensure the resources are not repeatedly claimed when not needed, or to be able to cleanup when they are no longer needed. Code similar to the following is typical:

     DEFPROCCloseFiles
     CLOSE#in%
     CLOSE#out%
     ENDPROC

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). Therefore it is likely that the routine will be called from ON ERROR statements:

     ON ERROR PROCCloseFiles:END

But this immediately causes a problem. What happens if the premature exit occurs before one or more of the variables used in PROCCloseFiles have been created? The result would be a No such variable error, which would activate the ON ERROR routine, which would call PROCCloseFiles, 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 a way of doing this:

     variable = variable

If variable already exists it is left unaltered, if variable doesn't exist it is created and its value is set to zero.

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

     DEFPROCCloseFiles
     in% =in% :IF in%  THEN A%=in% :in%=0 :CLOSE#A%
     out%=out%:IF out% THEN A%=out%:out%=0:CLOSE#A%
     ENDPROC

Additionally, this zeros the variable before using a copy of it, so if an error occurs within the PROCCloseFiles routine, the variable will have already zeroed and there won't be a repeated attempt to close the file again.

You can use this technique whenever you can't be sure whether a variable has been created or not. Another example is claiming memory. If you repeatedly claim memory pointed to by the same variable, you "leak" the previously claimed memory. Code similar to the following avoids this:

     mem%=mem%:IF mem%=0:DIM mem% size%

By JGH, Jun 2007. Based on article by Richard Russell for BBFW Wiki, May 2006