Structures

From m204wiki
Revision as of 00:15, 31 August 2011 by JAL2 (talk | contribs)
Jump to navigation Jump to search

A structure is, as the name suggests, a layout of standard User Language variables.

The layout of a structure is described by a Structure block, and variables with that layout are indicated by the Structure datatype on variable declarations.

Structure blocks and variable declaration

A Structure block has the following syntax:

Structure <structureName> [requiredSuffix=<suffix>]
   variable declarations ...
End Structure [structureName]

where structureName can consist of any valid alphanumeric and other non-separator characters, and suffix is a set of characters that must end the name of any variable being declared with the structure. The variables in a structure are sometimes referred to as the “structure members”.

Note: As of Sirius Mods version 7.3, you can also define “local” structures (“Local classes, enumerations, and structures” on page 381) that apply only in the scope in which they are defined, which may be within a class or a method or another level of the program.

The variable declarations consist of one or more declarations of exactly the same format as a User Language %variable declaration, with the exception that the variable names must not begin with a percent sign:

structure budgie
   name is string len 6
   color is string len 32
   age is fixed dp 2
end structure

Like a standard User Language %variable declaration, the keyword Is is optional. Valid datatypes include String, Float, Fixed, Longstring, and (as described later) Structure, Object, Collection, and Enumeration. Structure members can also be Arrays, but cannot be Static or Global. Structure members may contain an Initial clause that indicates the initial value for a member in an instance of the structure.

A Structure block does not actually define a structure variable, but instead it defines the layout that such a variable would have. To define a variable with the layout specified on the structure statement, simply specify a Structure variable:

%var [is] Structure <structureName>

The individual members of the structure variable can then be referenced in much the same way that image items are referenced, with the exception that a structure does not have to be Prepared:

structure budgie
   color is longstring
   size is float
end structure
%sunshine is structure budgie
%sunshine:color = 'blue'
%sunshine:size = 18

Structures also differ significantly from Images in that multiple variables can be declared with the same structure and that structure variables can be assigned to each other as a whole, rather than a member at a time:

%sunshine is structure budgie %tweetie is structure budgie %sunshine:color = 'blue' %sunshine:size = 18 %tweetie = %sunshine

Note: Structure assignment is assignment by value: the elements of the source structure are copied one by one (very efficiently) to the target structure, so that subsequent changes to the source structure variable do not affect the target.

For example, the following code would print “blue”,

%sunshine is structure budgie
%tweetie is structure budgie
%sunshine:color = 'blue'
%tweetie = %sunshine
%sunshine:color = 'yellow'
print %tweetie:color

in contrast to the behavior of object variables, described later, where assignment is by reference.

Working with structure variables

Structure variables can be passed as both input and output subroutine parameters:

%sunshine is structure budgie
%sunshine:color = 'blue'
call feed(%sunshine)
...
subroutine feed(%birdie is structure budgie)

Structure variables can be compared, though only for equality (order comparisons such as GE, LE, GT, and LT are not supported):

%sunshine is structure budgie
%tweetie is structure budgie
...
if %sunshine ne %tweetie then
  print 'More millet, please'
end if

Structures can be embedded inside of other structures:

structure bird
  color is longstring
  size is float
end structure
structure budgie
  name is string len 6
  stuff is structure bird
  age is fixed dp 2
end structure

In this case, members of inner structures are accessed by appending their names to the outer structure members:

%flapper is structure budgie
...
%flapper:stuff:color = 'green'

Structure variables can be arrays and structures can contain arrays:

structure auction
  item is string len 32
  nbids is fixed
  bid is fixed dp 2 array(20)
end structure
...
%onBlock is structure auction
%lot is structure auction array(50)

In this case, the subscripts must come after the variable name, the member name, or both, where appropriate:

%onBlock:bid(%i) = %input
...
%lot(%j):item = 'Tiffany lamp'
...
%lot(%x):bid(%y) = %bid

Structure variables reside in VTBL in space allocated at compile-time so, as stated earlier, have no need to be “prepared”. However, at times it may be useful to “prepare” a structure variable, that is, set it to its initial default values. Because there is no “Prepare Structure” statement, this is best accomplished either by setting the individual members or (more efficiently) by keeping a template or initial structure variable to assign to a structure variable which is to be logically “prepared”:

structure budgie
   name is string len 6
   color is string len 8 initial('blue')
end structure
%budgieTemplate is structure budgie
%sunshine is structure budgie
...
* Re-initialize %sunshine
%sunshine = %budgieTemplate

The RequiredSuffix parameter

The RequiredSuffix parameter on structure definitions, like the corresponding parameter on class definitions, provides a way of enforcing naming standards for structure variable names. For example, if you have a structure definition like this:

structure budgie requiredSuffix=.parakeet
   name is string len 6
   color is string len 8 initial('blue')
end structure

All Structure variables of type Budgie would have to end in the characters “.parakeet”, making it relatively east to detect references to this type of variable in User Language code:

%my.parakeet:color = 'blue'
...
%current.parakeet = %my.parakeet

Comparing structures and classes

Structures and structure variables provide a rich new facility to User Language programmers. Yet, oddly, the recommendation is to use them sparingly, and in general, to use Classes and Object variables instead. There are many reasons for this:

  • Assignment of object variables is much more efficient because only the reference (pointer) is actually copied, not all the values.
  • Object variables don't necessarily take up VTBL space and, in fact, are swapped out to CCATEMP as needed.
  • Object variables prevent multiple references to the same object.

While the first two points are important, the last is most critical to an applications programmer. To illustrate why this is so, consider a customer structure:

structure customer
   name is string len 64
   balance is fixed dp 2
end structure

Suppose two variables have this structure, and we assign one to another:

%currentCust is structure customer
%biggestCust is structure customer
...
%currentCust = %biggestCust
...
%currentCust:balance = %currentCust:balance - %fee

Now, presumably, we must fix the balance in %biggestCust or hope that %biggestCust is not referenced again. As more and more copies of the same customer's data are propagated around the code, the task of keeping them in synch becomes increasingly complicated. By using an object instead to represent the customer, this problem goes away because all the object variables that refer to the same customer would point to the same underlying object (assuming the application is properly designed). Any changes to the underlying object would be reflected immediately in all the references to that object.

Some basic guidelines for when a Structure is to be used instead of an object are:

  • Any data structure that represents a real entity or object — a noun, if you will — should be an object, not a structure. Structures should generally be used for measurements or attributes of objects.
  • Despite the richness of the structure facility, structures should be small, that is, with no more than five members and usually only two or three. If they get much bigger than this, it is likely that an object is a more appropriate model for the data being represented.
  • Any data structure that represents an attribute of an object or method — an adjective, if you will — might make sense as a Structure.
  • Because structures are statically allocated in VTBL, accessing data in a structure can be somewhat more efficient than accessing data in an object (and in an image, incidentally), so might be useful in cases where performance of individual member access is the paramount concern.

See also