ACS Documentation : ACS Core Architecture Guide : API Publication : Publishing Tcl Procedures
proc command to define
procedures poses two main problems:
proc.
regexp
command's -nocase switch), a procedure defined with
proc must include logic to parse its own argument list.
ad_proc instead of proc command to define
procedures, which provides automatic switch parsing (based
on an extended syntax for the argument list) and optionally accepts an
argument containing documentation for the procedure.
ad_proc that
provides several new features:
ad_proc, proc_doc, only
solved the first of the above problems and is deprecated as of ACS
3.4.)
ACS 3.4 also introduces the ad_library proc that
supersedes file header comments as the method of providing
documentation for the set of Tcl procedures in one library file.
ad_procad_proc is:
ad_proc [ -public | -private ] [ -deprecated [ -warn ] ] proc_name arg-list \
[ doc-string ] code-block
Here are descriptions of each switch that ad_proc itself
accepts:
The arg-list argument of
-public- proc_name is part of the enclosing package's public interface (a.k.a. API)
-private- proc_name is not part of the enclosing package's API
-deprecated- proc_name is obsolete and should not be called
-warn- the first time proc_name is called, it will automatically log a warning, so that the site maintainer will be notified and can remove the call to the deprecated procedure (requires that
-deprecatedalso be specified)
ad_proc defines the
syntax for the procedure proc_name, and consists of:
When invoking a procedure defined with
{ -switch_name default }- An optional switch that takes a default value of
defaultif no value is provided. The switch's value will be placed in$switch_name-switch_name- An optional switch that takes an argument with no default value. If the switch is provided, the argument will be placed in
$switch_name; if not, then$switch_namewill not be initialized (i.e.,info exists switch_namewill return 0).-switch_name:required- A required switch that takes an argument. The switch's value will be placed in
$switch_name.-switch_name:boolean- An optional boolean switch (see below). If the switch is provided,
$switch_name_pwill be set to 1; if not,$switch_name_pwill be set to 0.
ad_proc, boolean
switches can be specified in one of two ways, either:
-debug" in
ad_register_filter -debug preauth GET /* my_filter
-debug=n" in
This is useful when program logic determines the value for the switch at runtime, e.g.:ad_register_filter -debug=1 preauth GET /* my_filter
Without this feature, one would need to writead_register_filter -debug=$debug_p preauth GET /* ad_my_filter
if { $debug_p } {
ad_register_filter -debug preauth GET /* ad_my_filter
} else {
ad_register_filter preauth GET /* ad_my_filter
}
or build the command in a list and use eval.
ad_proc is
identical to declaring a positional argument with proc:
either just a name (for required arguments) or a two-element list
consisting of a name and default value (for optional arguments). As
with proc, the last positional argument can be
args, in which case the $args variable is
set to a list of any extra arguments supplied in the procedure call.
ad_register_filter, the ACS analog of
AOLserver's ns_register_filter:
ad_proc -public ad_register_filter {
-debug:boolean
-critical:boolean
{ -priority 10000 }
-description
kind method path proc args
} {
... documentation ...
} {
... code ...
}
The argument list is everything inside the braces immediately
following the procedure name ad_register_filter. The
switch declarations are the first four items
(-debug:boolean through -description), and
the positional arguments are the remaining items.
In the scope of the code block, $priority is always set
(to the supplied value of the -priority switch, or 10000
if omitted), whereas $description is only set if the
-description switch is provided. This is an important
distinction, since the semantics of omitting a switch are often
different from those of setting the value of a switch to be the empty
string.
The db_string proc (part of Database Access API) illustrates this
distinction clearly: If its optional -default switch is
provided, then it is OK for the query to return zero rows; the
supplied default value will be returned. However, if the switch is
omitted, then the query must return one row, or an error will be
raised.
Of course, the implementation of db_string (and of any
procedure that accepts optional switches) must handle both these
cases:
if { [info exists default] } {
# A default value was provided; zero rows are OK.
... code ...
} else {
# No default value; throw an error if the query
# returns zero rows.
... code ...
}
A documentation string consists of HTML-formatted text that informs the reader what the procedure does and how to use it correctly. The first sentence of the documentation string should be a standalone description of the procedure, as it will be presented in the summary view of the API Documentation Browser. Since the text of the documentation string will be interpreted as HTML, you must properly escape HTML characters that you don't want interpreted, such as <, > and &.
The main text of the documentation string is followed by a series of blocks that look like:
A documentation string can contain:@tag Comment for the tag
@author tags, each followed
by the name (and e-mail address, in parentheses) of an author of the
procedure
@param tags, each followed
by the name of a parameter and then a description
@return tag, followed
by a description of the return value
@error tag, followed by a
description of the conditions under which an error will be thrown
@see tags, followed by the
name of a related Tcl procedure.
@arguments tag, followed by an
HTML-formatted description of the command line syntax, which, for
ad_proc, would look like:
[ -public | -private ] [ -deprecated [ -warn ] ] >proc-name</em> <em>arg-list</em> \<br>
[ <em>doc-string</em> ] <em>code-block</em>
(In general, the @arguments tag is not necessary,
since the API Documentation Browser can generate these strings
automatically, but it may be useful to specify procedures with complex
syntax more precisely, e.g., mutually exclusive flags or flags that
require other flags.)
ad_proc ad_get_cookie {
-include_set_cookies:boolean
-default
name
} {
Returns the value of a cookie.
@author Jon Salz (jsalz@mit.edu)
@param include_set_cookies if provided, also examines
<code>Set-Cookie</code> headers in
<code>[ns_conn outputheaders]</code> for a cookie about
to be set.
@param default the default value for the cookie (in case the cookie
is not set).
@param name the name of the cookie.
@return the cookie's value.
@error if the cookie is not set, and no default value is provided.
@see ad_set_cookie
} {
# The code for the routine.
}
The corresponding, automatically-generated documentation will look
like this:
If a procedure is deprecated, this fact is so noted before the procedure's description:
ad_get_cookie
ad_get_cookie [ -include_set_cookies ] [ -default default ] nameReturns the value of a cookie.
- Switches:
- -include_set_cookies (Boolean) - if provided, also examines
Set-Cookieheaders in[ns_conn outputheaders]for a cookie about to be set.
-default (optional) - the default value for the cookie (in case the cookie is not set).- Parameters:
- name - the name of the cookie.
- Returns:
- the cookie's value.
- Error:
- if the cookie is not set, and no default value is provided.
- See Also:
- ad_set_cookie
set_the_usual_form_variables
set_the_usual_form_variables [ error_if_not_found_p ]Deprecated. Invoking this procedure generates a warning.For each parameter specified in an HTTP GET or POST query, ...
ad_library is:
ad_library doc-string
ad_library replaces the file header comment found at the
top of Tcl library files, i.e., files in the /tcl/
directory under the server root and *-procs.tcl files
under the /packages/ directory.
Like ad_proc, the documentation string format for
ad_library is based on Javadoc, i.e., a general
description of the library's function, followed optionally by a series
of named attributes tagged by @ signs:
@author tags, one for
each author; specify the author's name, followed by his or her email
address in parentheses
@creation-date tag, indicating
when the page was first created
@cvs-id tag containing the
page's CVS identification string; just use $Id$
when creating the file, and CVS will substitute an appropriate string
when you check the file in.
write:# # path from server root # # description # # author-contact-info, creation-date # # $Id$ #
# /packages/acs-core/00-proc-procs.tcl
ad_library {
description
@creation-date creation-date
@author author-contact-info
@cvs-id $Id$
}
Here's a real example from the ACS Core package:
# /packages/acs-core/00-proc-procs.tcl
ad_library {
Routines for defining procedures and libraries of procedures (<code>-procs.tcl</code>
files).
@creation-date 7 Jun 2000
@author Jon Salz (jsalz@mit.edu)
@cvs-id $Id$
}
ad_doc:
wheread_doc [ -public | -private ] [ -deprecated ] type name documentation
type is the kind of structure being
documented; name is its name, and
documentation is the same sort of documentation
described above. Allowable syntaxes will be:
Note that we define three syntaxes for describing NSV arrays and global variables. The first describes an array as a whole; the second describes one entry in an array, where the key is a pre-defined literal; the third describes what the value of the array entry will be for different keys, e.g.:
ad_doc nsv name ...
ad_doc nsv name(one_key) ...
ad_doc nsv name(\$key) ...Documents the usage of an NSV array. ad_doc global name ...
ad_doc global name(one_key) ...
ad_doc global name(\$key) ...Documents the usage of a script-global variable.
ad_doc nsv rp_registered_procs(\$method) {
A list of registered procs to be considered for HTTP requests
with method <em>method</em>.
@see ad_register_filter
@see ad_register_proc
}
(The backslash before the dollar sign is necessary to prevent the Tcl
interpreter from attempting to perform variable interpolation at the
time that ad_doc is invoked.)