Defining and Deleting Structures
A structure is created by executing a structure definition expression. This is an expression of the following form:
{ Structure_name, Tag_name1, : Tag_def1, ... : ..., Tag_namen : Tagdefn }
Tag names must be unique within a given structure, although the same tag name may be used in more than one structure. Structure and tag names follow the same rules as all PV-WAVE identifiers: they must begin with a letter, following characters may be letters, digits, or the underscore or dollar sign characters, and case is ignored.
As mentioned above, each tag definition is a constant, variable, or expression whose type and dimension defines the type and dimension of the field. The result of a structure definition expression is a structure definition that is global in scope and can be used to create variables of the particular structure type.
A structure that has already been defined may be referred to by simply enclosing the structure’s name in braces:
variable = { Structure_name }
The variable created as a result of this command is a structure of the designated name with all of its fields filled with zeros or null strings.
The variable created by the above statement and the structure definition {Structure_name} are separate entities. The variable is said to be of type {Structure_name}. The definition {Structure_name} is analogous to any data type, such as integer or double. Just as any number of values can be of type integer, any number of variables may reference a given structure definition.
When referring to a structure definition, the tag names need not be present, as in:
variable = { Structure_name, expr1, ..., exprn }
All of the expressions are converted to the type and dimension of the original tag definition. If a structure definition of the first form (where the tag names are present) is executed and the structure already exists, each tag name and the structure of each tag field definition must agree with the original definition or an error will result.
Example of Defining a Structure
Assume a star catalog is to be processed. Each entry for a star contains the following information: Star name, right ascension, declination, and an intensity measured each month over the last 12 months. A structure for this information is defined with the statement:
STAR = { CATALOG, NAME: '', RA: 0.0, DEC: 0.0, INTEN: FLTARR(12) }
This structure definition is the basis for all examples in this chapter.
The above statement defines a structure type named CATALOG in a variable named STAR, which contains four fields. The tag names are NAME, RA, DEC, and INTEN. The first field, NAME, contains a scalar string as given by its tag definition; the following two fields each contain floating-point scalars, and the fourth field, INTEN, contains a 12-element floating-point array. Note that the type of the constants, 0.0, is floating point. If the constants had been written as 0 the fields RA and DEC would contain integers.
Defining a Structure within a Structure
The following example shows how to embed or nest a structure within another structure definition.
; Create structure, STAR, of type CATALOG.
STAR = {CATALOG, NAME:'', RA:0.0}
; Create a second structure, STAR2, of type CATALOG2.
STAR2 = {CATALOG2, POS:0.0, DEC:0}
; Create a third structure ALL which contains the previously
; defined structures as fields. Note that the tag definition can
; be either the name of a structure definition ({CATALOG}) or a
; variable of type ; structure (STAR2).
ALL = {TOTAL, TAG1:{CATALOG}, TAG2:STAR2}
Deleting a Structure Definition
The DELSTRUCT procedure lets you delete a structure definition, as long as the structure definition is not referenced by any variables. To determine if a structure definition is referenced, use the STRUCTREF procedure. Variables that are local to a procedure or function can be deleted only by exiting the procedure or function. You can delete variables at the $MAIN$ level with the DELVAR procedure. Because structure definitions can include other structure definitions, the parent structure definition must be deleted before any nested structure definitions can be deleted.
The DELSTRUCT procedure should only be used at the $MAIN$ level and is primarily designed to allow developers to modify named structure definitions without restarting their PV-WAVE session. PV-WAVE structure definitions are optimized to reduce memory use; they contain no data and only one definition exists in memory for a particular structure type, no matter how many structure variables of that type are declared. Repeatedly deleting and re-defining named structure definitions in your code is generally a poor practice and leads to instability.
For more information on DELSTRUCT and STRUCTREF, see the PV‑WAVE Reference.
Creating Unnamed Structures
As noted previously, a typical structure definition consists of a name and a list of fields. You can also create a structure that you do not name.
Unnamed structures are useful if you:
do not want to use a structure definition globally.
do not want to invent new names for structure definitions.
want the structure definition to be deleted automatically when it is no longer referenced.
want to create a structure-type variable that contains an array field that can vary.
Scope of Named and Unnamed Structures
Named structure definitions are global in scope. A named structure definition is created only once and then can be referenced by any number of variables. It is important to note that a named structure definition is not associated directly with any particular variable.
An unnamed structure, on the other hand, is closely associated with a specific variable. When the variable that is associated with an unnamed structure is deleted, so is the unnamed structure definition.
Syntax of an Unnamed Structure Definition
The syntax of an unnamed structure definition is:
x = {, tag_name1: tag_def1, tag_namen: tag_defn}
The data type of variable x references the unnamed structure definition. Unlike named structure definitions, when all variables that reference an unnamed structure definition are deleted, the unnamed structure definition is also deleted. If you copy a variable that references an unnamed structure definition (e.g., y = x), then both variables reference the same unnamed structure definition. Only when both variables are deleted will the unnamed structure definition be deleted.
Creating Variable-length Array Fields
The unnamed structure definition can be useful if you want to create a structure definition that contains array fields whose lengths can change. For example, suppose you want to create several variables that have the same structure except that one element is an array that you want to have different lengths for different variables. Using named structures, you would have to create a different structure for each case (because named structure definitions cannot be altered). For example:
a={structa, xdim:2, ydim:4, arr:intarr(2,4)}
b={structb, xdim:2, ydim:8, arr:intarr(2,8)}
However, the unnamed structure allows you to solve this problem. For example, the following function returns a structure-type variable whose tag names are the same, but whose array length is different for each variable:
function my_struct, x, y
RETURN, { , xdim:x,ydim:y, array:intarr(x,y)}
END
Now, you can create a and b as follows:
a = my_struct(2, 4)
b = my_struct(2, 8)
Internal Names of Unnamed Structures
PV-WAVE generates a name internally for an unnamed structure definition. This name always begins with a $. This ensures that an unnamed structure definition will never conflict with a named structure definition (because identifiers cannot begin with $).
The INFO command lets you see this internal name:
INFO, a, /Struct
; PV-WAVE prints the following:
; *** Structure $2, 3 tags, 20 length:
; XDIM INT 2
; YDIM INT 4
; ARRAY INT Array(2, 4)
note | Do not attempt to use the internal name for an unnamed structure in any other command. For example: c = {$2} or PRINT, STRUCTREF({$2}) In these cases, the $ character is interpreted as a line continuation character. The remainder of the line after $ is ignored, and PV-WAVE waits for you to enter the rest of the command on the next line. No error message is displayed until you enter another line that does not contain a $. |