Structures: Difference between revisions

From m204wiki
Jump to navigation Jump to search
mNo edit summary
 
(8 intermediate revisions by 3 users not shown)
Line 1: Line 1:
A '''structure''' is, as the name suggests, a layout of standard User Language variables.
A '''structure''' is, as the name suggests, a layout of standard <var class="product">SOUL</var> 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.  
The layout of a structure is described by a <var>Structure</var> block, and variables with that layout are indicated by the <var>Structure</var> datatype on variable declarations.  


==Structure blocks and variable declaration==
==Structure blocks and variable declaration==
A Structure block has the following syntax:
A <var>Structure</var> block has the following syntax:
<p class="syntax">Structure <span class="term">structureName</span> [requiredSuffix=<span class="term">suffix</span>]
  <span class="term">variable declarations</span> ...
End Structure [<span class="term">structureName</span>]  </p>


Structure <structureName> [requiredSuffix=<suffix>]
Where:
    variable declarations ...
<ul>
End Structure [structureName]
<li><var class="term">structureName</var> can consist of any valid alphanumeric and other non-separator characters. </li>


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”.
<li><var class="term">suffix</var> is a set of characters that must end the name of any variable being declared with the structure. </li>


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.
<li>The variables in a structure are sometimes referred to as the "structure members." </li>
</ul>


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:
<p class="note"><b>Note:</b> You can also define [[Local and Common entities#Local classes, enumerations, and structures|"local"]] structures 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. </p>


structure budgie
The variable declarations consist of one or more declarations of exactly the same format as a <var class="product">SOUL</var> %variable declaration, with the exception that the variable names must not begin with a percent sign:
    name is string len 6
<p class="code">structure budgie
    color is string len 32
  name is string len 6
    age is fixed dp 2
  color is string len 32
end structure
  age is fixed dp 2
end structure
</p>


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.
Like a standard <var class="product">SOUL</var> %variable declaration, the keyword <var>Is</var> is optional. Valid datatypes include <var>String</var>, <var>Float</var>, <var>Fixed</var>, <var>Longstring</var>, and (as described later) <var>Structure</var>, <var>Object</var>, <var>Collection</var>, and <var>Enumeration</var>. A <var>Structure</var> member can also be an <var>Array</var>, but it cannot be <var>Static</var> or <var>Global</var>. 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:
A <var>Structure</var> 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 <var>Structure</var> variable:


%var [is] Structure <structureName>
<p class="syntax"><span class="term">%var</span> [is] Structure <span class="term">structureName</span>  </p>


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:
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
<p class="code">structure budgie
    color is longstring
  color is longstring
    size is float
  size is float
end structure
end structure
%sunshine is structure budgie
%sunshine is structure budgie
%sunshine:color = 'blue'
%sunshine:color = 'blue'
%sunshine:size = 18
%sunshine:size = 18 </p>


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:
Structures also differ significantly from <var>Images</var> 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:


<p class="code">%sunshine is structure budgie
<p class="code">%sunshine is structure budgie
Line 47: Line 53:
%tweetie = %sunshine </p>
%tweetie = %sunshine </p>


'''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.
<blockquote class="note">
<p>'''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 <var>Structure</var> variable do not affect the target. </p>
<p>
For example, the following code prints <code>blue</code>: </p>


For example, the following code would print “blue”,
<p class="code">%sunshine is structure budgie
 
%tweetie is structure budgie
%sunshine is structure budgie
%sunshine:color = 'blue'
%tweetie is structure budgie
%tweetie = %sunshine
%sunshine:color = 'blue'
%sunshine:color = 'yellow'
%tweetie = %sunshine
print %tweetie:color </p>
%sunshine:color = 'yellow'
print %tweetie:color


in contrast to the behavior of object variables, described later, where assignment is by reference.
The behavior of object variables contrasts with this: assignment is by reference, as described later.
</blockquote>


==Working with structure variables==
==Working with structure variables==
Structure variables can be passed as both input and output subroutine parameters:
Structure variables can be passed as both input and output subroutine parameters:


%sunshine is structure budgie
<p class="code">%sunshine is structure budgie
%sunshine:color = 'blue'
%sunshine:color = 'blue'
call feed(%sunshine)
call feed(%sunshine)
  ...
  ...
subroutine feed(%birdie is structure budgie)
subroutine feed(%birdie is structure budgie) </p>


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


%sunshine is structure budgie
<p class="code">%sunshine is structure budgie
%tweetie is structure budgie
%tweetie is structure budgie
  ...
  ...
if %sunshine ne %tweetie then
if %sunshine ne %tweetie then
  print 'More millet, please'
  print 'More millet, please'
end if
end if </p>


Structures can be embedded inside of other structures:
Structures can be embedded inside of other structures:


structure bird
<p class="code">structure bird
  color is longstring
  color is longstring
  size is float
  size is float
end structure
end structure
structure budgie
structure budgie
  name is string len 6
  name is string len 6
  stuff is structure bird
  stuff is structure bird
  age is fixed dp 2
  age is fixed dp 2
end structure
end structure </p>


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


%flapper is structure budgie
<p class="code">%flapper is structure budgie
  ...
  ...
%flapper:stuff:color = 'green'
%flapper:stuff:color = 'green' </p>


Structure variables can be arrays and structures can contain arrays:
A structure variable can be an <var>Array</var>, and structures can contain <var>Array</var>s:


structure auction
<p class="code">structure auction
  item is string len 32
  item is string len 32
  nbids is fixed
  nbids is fixed
  bid is fixed dp 2 array(20)
  bid is fixed dp 2 array(20)
end structure
end structure
  ...
  ...
%onBlock is structure auction
%onBlock is structure auction
%lot is structure auction array(50)
%lot is structure auction array(50) </p>


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


%onBlock:bid(%i) = %input
<p class="code">%onBlock:bid(%i) = %input
  ...
  ...
%lot(%j):item = 'Tiffany lamp'
%lot(%j):item = 'Tiffany lamp'
  ...
  ...
%lot(%x):bid(%y) = %bid
%lot(%x):bid(%y) = %bid </p>


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 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
<p class="code">structure budgie
    name is string len 6
  name is string len 6
    color is string len 8 initial('blue')
  color is string len 8 initial('blue')
end structure
end structure
%budgieTemplate is structure budgie
%budgieTemplate is structure budgie
%sunshine is structure budgie
%sunshine is structure budgie
  ...
  ...
* Re-initialize %sunshine
&#42; Re-initialize %sunshine
%sunshine = %budgieTemplate
%sunshine = %budgieTemplate </p>


==The RequiredSuffix parameter==
==The RequiredSuffix parameter==
The <var>RequiredSuffix</var> 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:
The <var>RequiredSuffix</var> 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
<p class="code">structure budgie requiredSuffix=.parakeet
    name is string len 6
  name is string len 6
    color is string len 8 initial('blue')
  color is string len 8 initial('blue')
end structure
end structure </p>


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:
All <var>Structure</var> variables of type <code>Budgie</code> would have to end in the characters <code>.parakeet</code>, making it relatively east to detect references to this type of variable in <var class="product">SOUL</var> code:
%my.parakeet:color = 'blue'
<p class="code">%my.parakeet:color = 'blue'
  ...
  ...
%current.parakeet = %my.parakeet
%current.parakeet = %my.parakeet </p>


==Comparing structures and classes==
==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:
Structures and structure variables provide a rich new facility to <var class="product">SOUL</var> 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:
<ul>
<li>Assignment of object variables is much more efficient because only the reference (pointer) is actually copied, not all the values. </li>


* Assignment of object variables is much more efficient because only the reference (pointer) is actually copied, not all the values.
<li>Object variables don't necessarily take up VTBL space and, in fact, are swapped out to CCATEMP as needed. </li>
* 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:
<li>Object variables prevent multiple references to the same object. </li>
</ul>


structure customer
While the first two points are important, the last is most critical to an applications programmer. To illustrate why this is so, consider a <code>customer</code> <var>Structure</var>:
 
<p class="code">structure customer
     name is string len 64
     name is string len 64
     balance is fixed dp 2
     balance is fixed dp 2
  end structure
  end structure </p>


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


%currentCust is structure customer
<p class="code">%currentCust is structure customer
%biggestCust is structure customer
%biggestCust is structure customer
  ...
  ...
%currentCust = %biggestCust
%currentCust = %biggestCust
  ...
  ...
%currentCust:balance = %currentCust:balance - %fee
%currentCust:balance = %currentCust:balance - %fee </p>
 
Now, presumably, you must fix the <code>balance</code> in <var class="term">%biggestCust</var> or hope that <var class="term">%biggestCust</var> 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 sync become 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 <var>Structure</var> is to be used instead of an object are:


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.
<ul>
<li>Any data structure that represents a real entity or object &mdash; a noun, if you will &mdash; should be an object, not a structure. Structures should generally be used for measurements or attributes of objects. </li>


Some basic guidelines for when a Structure is to be used instead of an object are:
<li>Despite the richness of the <var>Structure</var> 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. </li>


* 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.
<li>Any data structure that represents an attribute of an object or method &mdash; an adjective, if you will &mdash; might make sense as a <var>Structure</var>. </li>
* 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.
<li>Because structures are statically allocated in VTBL, accessing data in a <var>Structure</var> can be somewhat more efficient than accessing data in an <var>Object</var> (and in an <var>Image</var>, incidentally), so might be useful in cases where performance of individual member access is the paramount concern.
* 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.
</li>
</ul>


==See also==
==See also==
Line 176: Line 193:
<li>[[Classes and Objects]]
<li>[[Classes and Objects]]
<li>[[Object variables]]
<li>[[Object variables]]
<li>[[Copying objects]]
<li>[[Global and session objects]]
<li>[[Managing server space for objects]]
<li>[[Methods]]
<li>[[Methods]]
<li>[[Lists of classes and methods]]
<li>[[Object oriented programming in SOUL]]
<li>[[Enumerations]]
<li>[[Janus SOAP User Language Interface|Janus SOAP ULI]]
<li>[[Getting started with object-oriented programming for User Language programmers]]
</ul>
</ul>
[[Category:SOUL object-oriented programming topics]]

Latest revision as of 16:49, 24 May 2016

A structure is, as the name suggests, a layout of standard SOUL 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.
  • 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: You can also define "local" structures 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 SOUL %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 SOUL %variable declaration, the keyword Is is optional. Valid datatypes include String, Float, Fixed, Longstring, and (as described later) Structure, Object, Collection, and Enumeration. A Structure member can also be an Array, but it 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 prints blue:

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

The behavior of object variables contrasts with this: assignment is by reference, as described later.

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'

A structure variable can be an Array, 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 SOUL code:

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

Comparing structures and classes

Structures and structure variables provide a rich new facility to SOUL 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 you assign one to the other:

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

Now, presumably, you 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 sync become 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