LOCAL

LOCAL

Top  Previous  Next

 

The LOCAL statement introduces an internal function or subroutine that may have private local variables.

 

 

Format

 

LOCAL {FUNCTION | SUBROUTINE} name{(args)}

PRIVATE vars

...statements...

END

 

where

 

nameis the name of the function subroutine.

 

argsis the comma separated list of arguments to the function or subroutine. An argument may reference a whole matrix by prefixing it with MAT. The variable names used for the arguments are visible only to the one function or subroutine and do not prevent use of the same name in other parts of the program module to reference a different variable. Enclose the argument name in parenthesis to pass it by value.

 

 

When passing a whole matrix as an argument to a local function or subroutine, a DIM statement can be used within the body of the local function or subroutine to re dimension the matrix. This is not the same behaviour as applying DIM to a matrix passed as an argument to an external subroutine where the DIM statement merely specifies the number of dimensions, the actual dimension values being ignored.

 

Further local variables that are private to the function or subroutine may be defined by immediately following the LOCAL statement by one or more PRIVATE statements. These contain a comma separated list of variable names which may be simple scalar items or matrices where the dimension values are numeric constants. Any variables referenced in the local function or subroutine but not declared as private are considered as having scope across the entire program module.

 

Functions and subroutines declared using LOCAL must be terminated with an END statement. The private variables declared using the PRIVATE statement have scope from the LOCAL statement until the corresponding END statement. Variables referenced in the main body of the program and in conventional internal subroutines are accessible unless they have the same name as a locally defined variable.

 

A local function must be defined using the DEFFUN statement with the LOCAL option before its first use in the program.

 

All labels within the local subroutine are private. It is not possible to jump into a subroutine declared with LOCAL except by using a GOSUB or ON GOSUB to its unique entry point. Similarly, it is not possible to jump to a label outside the local subroutine. Use of the RETURN TO statement is prohibited within a local subroutine.

 

If a local subroutine is called recursively, either directly or indirectly via some other intermediate subroutine, the local variables are stacked and the new invocation has its own private local variables.

 

There is a small performance cost by comparison to use of conventional internal subroutines due to the dynamic allocation of variables but this should be negligible in most applications.

 

When using the QMBasic debugger, local variables have a name formed from the subroutine name and variable name separated by a colon.

 

 

Examples

 

LOCAL SUBROUTINE SCAN.LIST

  PRIVATE I, N, REC

  N = DCOUNT(LIST, @FM)

  FOR I = 1 TO N

     READV REC FROM STOCK.F, LIST<I> , 0 ELSE

        DISPLAY LIST<I> : ' is not in stock file'

     END

  NEXT I

  RETURN

END

 

The above program fragment represents a local subroutine that scans a list, checking that each entry corresponds to a record in a file. By using LOCAL and three local variables, all risk of overwriting valuable data in variables of the same names in the main body of the program is removed.

 

 

LOCAL FUNCTION NEXT.ID(FILENAME)

  PRIVATE DICT.F, ID

  OPEN 'DICT', FILENAME TO DICT.F THEN

     READU ID FROM DICT.F, 'NEXT.ID' THEN

        WRITE ID+1 TO DICT.F, 'NEXT.ID'

        RETURN ID

     END

  END

  RETURN ''

END

 

The above local function takes a file name as its argument and gets the next sequential record id from a record stored in the corresponding dictionary, returning this as the value of the function. The dictionary will automatically be closed when the DICT.F variable is discarded on return from the function.