A procedure in BASIC is either a SUB or FUNCTION (or SUBI and FUNCTIONI).
It's functionally the same as GOSUB and RETURN but introduces the concept of
parameters and return values. Unlike QBasic, a FUNCTION can also be called
as a SUB. Meaning you can ignore its return value.
DECLARE SUB
Use DECLARE SUB whenever you want to provide a "forward" declaration without
actually writing the SUB yet.
DECLARE SUB Test
CALL Test
SUB Test
'' Do Stuff
END SUB
Using CALL to call your subroutine is strictly optional. As you can see,
we're providing a forward declaration of the SUB Test.
To avoid using DECLARE SUB, you could have written the SUB Test before
CALLing it.
SUB Test
END SUB
Test
This way you don't need to use DECLARE SUB. Please note that your parameter names
in the DECLARE SUB and your actual SUB declaration MUST MATCH exactly!
If you're not sure what I mean, take this for example:
DECLARE SUB Test (A AS INTEGER, B AS INTEGER)
SUB Test (X AS INTEGER, Y AS INTEGER)
PRINT X;" ";Y
END SUB
Don't change the variable names! This is because when you defined your DECLARE SUB,
the parameter names have been fixed as A and B, which also means you can
comfortably do this:
DECLARE SUB Test (A AS INTEGER, B AS INTEGER)
SUB Test
PRINT A;" ";B
END SUB
This is perfectly valid, since you've already declared your subroutine to have an
A and B parameter. You don't actually need to define parameters if you already have
a forward declaration in place. Obviously this can become confusing so it's
not recommended.
Passing variables by reference
There are 2 ways to pass variables by reference. Unlike other BASIC languages,
Rapid-Q assumes that all parameters are passed by value unless explicitly
specified. To do this explicitly, you can attach a BYREF keyword in front of
your parameter list. Here's an example
SUB StrCat (BYREF Source AS STRING, Text AS STRING)
Source = Source + Text
END SUB
A$ = "Hello"
StrCat A$, " world!"
PRINT A$ '-- returns "Hello world!"
Another way is to prepend an '@' symbol in front of the variable:
SUB StrCat (Source AS STRING, Text AS STRING)
Source = Source + Text
END SUB
A$ = "Hello"
StrCat @A$, " world!"
PRINT A$ '-- returns "Hello world!"
FUNCTIONs versus SUBs
The only difference between a FUNCTION and a SUB is that a FUNCTION returns a
value.
FUNCTION Test AS INTEGER
Test = 123
Result = 123
END FUNCTION
Rval% = Test
Our FUNCTION Test returns an INTEGER, which we can clearly see returns 123.
To return a value, you can use the FUNCTION's name or use the keyword
Result.
Just because you've attached a return value to the FUNCTION, it does not automatically
terminate until it reaches your END FUNCTION. So you can really assign as many return
values as you like without consequences. The last return value assigned will ultimately
be the one bound to your FUNCTION. To exit a FUNCTION or SUB, just use EXIT FUNCTION, or
EXIT SUB respectively. One special case in using SUBs or FUNCTIONs in Rapid-Q is
that you can only pass at most 10 parameters. QObjects, Arrays, UDTs and Variants are passed by reference, everything
else is passed by value. In order for Rapid-Q to recognize that you want to
pass a variable by reference, you must attach an @ symbol in front of the variable, or
use BYREF in your parameter list.
See Chapter 3 section 5 for more information.
SUBI and FUNCTIONI
There's a whole chapter reserved for these two procedure methods. It's not really
that complicated, but is very handy to use. They provide the programmer with
infinite parameters without type checking. Only simple types like numbers and
strings can be passed, no Arrays, UDTs or QObjects.
See Chapter 9 for all the details.