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_proc
ad_proc
is:
Here are descriptions of each switch thatad_proc [ -public | -private ] [ -deprecated [ -warn ] ] proc_name arg-list \ [ doc-string ] code-block
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
-deprecated
also 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
default
if 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_name
will not be initialized (i.e.,info exists switch_name
will 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_p
will be set to 1; if not,$switch_name_p
will 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
or build the command in a list and useif { $debug_p } { ad_register_filter -debug preauth GET /* ad_my_filter } else { ad_register_filter preauth GET /* ad_my_filter }
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
:
The argument list is everything inside the braces immediately following the procedure namead_proc -public ad_register_filter { -debug:boolean -critical:boolean { -priority 10000 } -description kind method path proc args } { ... documentation ... } { ... code ... }
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:
(In general, the[ -public | -private ] [ -deprecated [ -warn ] ] >proc-name</em> <em>arg-list</em> \<br> [ <em>doc-string</em> ] <em>code-block</em>
@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.)
The corresponding, automatically-generated documentation will look like this: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. }
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-Cookie
headers 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$ #
Here's a real example from the ACS Core package:# /packages/acs-core/00-proc-procs.tcl ad_library { description @creation-date creation-date @author author-contact-info @cvs-id $Id$ }
# /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.
(The backslash before the dollar sign is necessary to prevent the Tcl interpreter from attempting to perform variable interpolation at the time thatad_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 }
ad_doc
is invoked.)