|
3.9.1 Procedures in a library
In this section we list miscellaneous recommendations on how procedures
contained in a library should be implemented.
-
The info- and version-string should appear at the beginning of the
library, before procedure definitions.
-
The info-string should have the format as explained in The help string of a library.
-
Each procedure which should not be accessible by users should be
declared
static .
-
Each procedure which is not declared
static should have a
help and example section as explained in Procedure definition.
Such procedures should furthermore carefully check any assumptions
made about their input (like the type of list elements), and, if
necessary, omit an error using the function ERROR.
-
No procedures should be defined within the body of another procedure.
-
If the value of
the reserved variable
printlevel (see printlevel) is greater
than 0 then interactive user-input, i.e., the usage of functions like
pause("..") or read(""); (see read), may be requested.
-
If the value of
the reserved variable
printlevel (see printlevel) is 0
then interactive user-input, i.e., the usage of functions like
pause("..") or read(""); (see read), may not be
requested. Instead, an error (using the function
ERROR) should be reported together with the recommendation on
increasing the value of the reserved variable printlevel .
-
It is often useful for a procedure to print out comments, either to
explain results or to display intermediate computations. However,
if this procedure is called by another procedure, such comments are
confusing and disturbing in most cases.
SINGULAR offers an elegant solution, which requires the usage of
the SINGULAR function dbprint and the reserved variables
printlevel, and voice (voice counts the nesting of
procedures; It has the value 1 on the top level, 2 inside the first
procedure etc.; printlevel has the value 0 by default, but can be
set to any integer value by the user).
For example, if the following procedure Test is called
directly from the top level then ‘comment1’ is displayed (i.e.,
printed out) but not
‘comment2’; and nothing is displayed if Test is called
from within any other procedure.
However, if printlevel is set to a value k with k>0, then
‘comment1’ (resp. ‘comment2’) is displayed provided that
Test is called from other procedures, with a nesting level up to
k (resp. k-1).
Note furthermore, that the example part of a procedure
behaves in this respect like a procedure (i.e., the value of voice
is 1). Therefore, the command printlevel=1; is necessary for
‘comment1’ to be displayed on example Test; . However,
since printlevel is a global variable, it should be reset to the old
value at the end of the example part.
| proc Test
"USAGE: ...
...
EXAMPLE: example Test; shows an example
"
{ ...
int p = printlevel - voice + 3;
...
dbprint(p,"comment1");
dbprint(p-1,"comment2");
// dbprint prints only if p > 0
...
}
example
{ "EXAMPLE:"; echo = 2;
int p = printlevel; //store old value of printlevel
printlevel = 1; //assign new value to printlevel
...
Test();
printlevel = p; //reset printlevel to old value
}
|
|