Arrays

EGL supports the following kinds of arrays:

In either case, the maximum number of supported dimensions is seven.

Dynamic arrays

When you declare an array of primitive variables or of records (type BasicRecord, DLISegment, or SQLRecord), the array has an identity independent of the elements in the array:
  • A set of functions are specific to the array, allowing you to grow or shrink the number of elements at run time.
  • The array-specific property maxSize indicates how many elements are valid in the array. The default value is unbounded; the number of elements is limited only by the requirements of the target environment.

You do not need to specify a number of elements in your declaration, but if you do, that number indicates the initial number of elements. You also can specify the initial number of elements by listing a series of array constants in the declaration, as is possible only with primitive variables, not with records.

The syntax for declaring a dynamic array is shown in the following examples:

  // An array of 5 elements or less
  myDataItem01 CHAR(30)[] { maxSize=5 };

  // An array of 6 elements or less, 
  // with 4 elements initially
  myDataItem02 myDataItemPart[4] { maxSize=6 };

  // An array that has no elements 
  // but whose maximum size is the largest possible
  myRecord myRecordPart[];

  // A 3-element array whose elements 
  // are assigned the values 1, 3, and 5
  position int[] = [1,3,5]; 

You can use a literal integer to initialize the number of elements, but neither a variable nor a constant is valid.

When you declare an array of arrays, an initial number of elements is valid in the leftmost-specified dimension and in each subsequent dimension until a dimension lacks an initial number. The following declarations are valid:
  // Valid, with maxsize giving the maximum 
  // for the first dimension
  myInt01 INT[3][];
  myInt02 INT[4][2][] {maxsize = 12};
  myInt03 INT[7][3][1];

  // In the next example, array constants indicate 
  // that the outer array initially has 3 elements.
  // The first element of the outer array is 
  // an array of two elements (with values 1 and 2).
  // The second element of the outer array is
  // an array of three elements (with values 3, 4,5).
  // The third element of the outer array is 
  // an array of two elements (with values 6 and 7).
  myInt04 INT[][] = [[1,2],[3,4,5],[6,7]];
In the following example, the syntax is not valid because (for instance) the array myInt04 is declared as an array of no elements, but each of those elements is assigned 3 elements:
  // NOT valid
  myInt04 INT[][3];
  myInt05 INT[5][][2];

An array specified as a program or function parameter cannot specify the number of elements.

When your code references an array or an array element, these rules apply:
  • An element subscript can be any numeric expression that resolves to an integer, but the expression cannot include a function invocation.
  • If your code refers to a dynamic array but does not specify subscripts, the reference is to the array as a whole.

An out-of-memory situation is treated as a catastrophic error and ends the program.

Dynamic-array functions

A set of functions and read-only variables are available for each dynamic array. In the following example, the array is called series:
  series.reSize(100);
The name of the array may include a set of brackets, each containing an integer. An example is as follows:
  series INT[][];

  // resizes the second element 
  // of series, which is an array of arrays 
  series[2].reSize(100);

In the following sections, substitute the array name for arrayName and note that the name may be qualified by a package name, a library name, or both.

appendAll()

  arrayName.appendAll(appendArray  Array in)
This function does as follows:
  • Appends to the array that is referenced by arrayName, adding a copy of the array that is referenced by appendArray
  • Increments the array size by the number of added elements
  • Assigns an appropriate index value to each of the appended elements

The elements of appendArray must be of the same type as the elements of arrayName.

appendElement()

  arrayName.appendElement(content ArrayElement in)

This function places an element to the end of the specified array and increments the size by one. For content, you can substitute a variable of the appropriate type; alternatively, you can specify a literal that is assigned to an element created during the operation. The process copies data; if you assign a variable, that variable is still available for comparison or other purposes.

The rules for assigning a literal are as specified in Assignments.

getMaxSize()

  arrayName.getMaxSize ( ) returns (INT)

This function returns an integer that indicates the maximum of elements allowed in the array.

getSize()

  arrayName.getSize ( ) returns (INT)

This function returns an integer that indicates the number of elements in the array. It is recommend that you use this function instead of SysLib.size when you are working with dynamic arrays.

Another function provides functionality equivalent to that of arrayName.getSize:
SysLib.size( ) returns (INT)

However, it is recommended that you use arrayName.getSize ( ) when you work with dynamic arrays.

insertElement()

  arrayName.insertElement (content ArrayElement in, index INT in)
This function does as follows:
  • Places an element in front of the element that is now at the specified location in the array
  • Increments the array size by one
  • Increments the index of each element that resides after the inserted element

content is the new content (a constant or variable of the appropriate type for the array), and index is an integer literal or a numeric variable that indicates the location of the new element.

If index is one greater than the number of elements in the array, the function creates a new element at the end of the array and increments the array size by one.

removeAll()

  arrayName.removeAll( )

This function removes the elements of the array from memory. The array can be used, but its size is zero.

removeElement()

  arrayName.removeElement(index INT in)

This function removes the element at the specified location, decrements the array size by one, and decrements the index of each element that resides after the removed element.

index is an integer literal or a numeric variable that indicates the location of the element to be removed.

resize()

  arrayName.resize(size INT in)

This function adds or shrinks the current size of the array to the size specified in size, which is an integer literal, constant, or variable. If the value of size is greater than the maximum size allowed for the array, the run unit terminates.

reSizeAll()

  arrayName.reSizeAll(sizes INT[
] in)

This function adds or shrinks every dimension of a multidimensional array. The parameter sizes is an array of integers, with each successive element specifying the size of a successive dimension. If the number of dimensions resized is greater than the number of dimensions in arrayName, or if a value of an element in sizes is greater than the maximum size allowed in the equivalent dimension of arrayName, the run unit terminates.

setMaxSize()

  arrayName.setMaxSize (size INT in)

The function sets the maximum of elements allowed in the array. If you set the maximum size to a value less than the current size of the array, the run unit terminates.

setMaxSizes()

  arrayName.setMaxSizes(sizes INT[
] in)

This function sets every dimension of a multidimensional array. The parameter sizes is an array of integers, with each successive element specifying the maximum size of a successive dimension. If the number of dimensions specified is greater than the number of dimensions in arrayName, or if a value of an element in sizes is less than the current number of elements in the equivalent dimension of arrayName, the run unit terminates.

Use of dynamic arrays as arguments and parameters

A dynamic array can be passed as an argument to an EGL function. The related parameter must be defined as a dynamic array of the same type as the argument; and for a data item, the type must include the same length and decimal places, if any.

A dynamic array of the following types can be passed to a program:
  • A primitive type
  • A record of type BasicRecord, DLISegment, or SQLRecord
An example of a function that uses a dynamic array as a parameter is as follows:
  Function getAll (employees Employee[])
   ;
  end

At run time, the maximum size for a parameter is the maximum size declared for the corresponding argument. The invoked function can change the size of the array, and the change is in effect in the invoking code.

SQL processing and dynamic arrays

EGL lets you use a dynamic array to access rows of a relational database. For details on reading multiple rows, see get. For details on adding multiple rows, see add.

Structure-field arrays

You declare a structure-field array when you specify that a field in a fixed structure has an occurs value greater than one, as in the following example:
  Record myFixedRecordPart
    10 mySi CHAR(1)[3];
  end

If a fixed record called myRecord is based on that part, the symbol myRecord.mySi refers to a one-dimensional array of three elements, each a character.

Usage of a structure-field array

You can reference an entire array of structure fields (for example, myRecord.mySi) in these contexts:
  • As the second operand used by an in operator. The operator tests whether a given value is contained in the array.
  • As the parameter in the function sysLib.size. That function returns the occurs value of the structure field.

An array element that is not itself an array is a field like any other, and you can reference that field in various ways; for example, in an assignment statement or as an argument in a function invocation.

An element subscript can be any numeric expression that resolves to an integer, but the expression cannot include a function invocation.

One-dimensional structure-field array

You can refer to an element of a one-dimensional array like myRecord.mySi by using the name of the array followed by a bracketed subscript. The subscript is either an integer or a field that resolves to an integer; for example, you can refer to the second element of the example array as myStruct.mySi[2]. The subscript can vary from 1 to the occurs value of the structure field, and a runtime error occurs if the subscript is outside of that range.

If you use the name of a structure-field array in a context that requires a field but do not specify a bracketed subscript, EGL assumes that you are referring to the first element of the array, but only if you are in VisualAge® Generator compatibility mode. It is recommended that you identify each element explicitly. If you are not in VisualAge Generator compatibility mode, you are required to identify each element explicitly.

The next examples show how to refer to elements in a one-dimensional array. In those examples, valueOne resolves to 1 and valueTwo resolves to 2:
  // these refer to the first of three elements:
  myRecord.mySi[valueOne]

  // not recommended; and valid 
  // only if VisualAge Generator
  // compatibility is in effect:
  myRecord.mySi                                    

  // this refers to the second element:
  myRecord.mySi[valueTwo]
A one-dimensional array may be substructured, as in this example:
  record myRecord01Part
    10 name[3];
      20 firstOne CHAR(20);
      20 midOne CHAR(20);
      20 lastOne CHAR(20);
  end

If a record called myRecord01 is based on the previous part, the symbol myRecord01.name refers to a one-dimensional array of three elements, each of which has 60 characters, and the length of myRecord01 is 180.

You may refer to each element in myRecord01.name without reference to the substructure; for example, myRecord01.name[2] refers to the second element. You also may refer to a substructure within an element. If uniqueness rules are satisfied, for example, you can reference the last 20 characters of the second element in any of the following ways:

  myRecord01.name.lastOne[2]
  myRecord01.lastOne[2]	
  lastOne[2]

The last two are valid only if the generatable-part property allowUnqualifiedItemReferences is set to yes.

For details on the different kinds of references, see References to variables and constants.

Multidimensional structure-field array

If a structure item with an occurs value greater than one is substructured and if a subordinate structure item also has an occurs value greater than one, the subordinate structure item declares an array with an additional dimension.

Let's consider another record part:
  record myRecord02Part
    10 siTop[3];
      20 siNext CHAR(20)[2];
  end
If a record called myRecord02 is based on that part, each element of the one-dimensional array myRecord02.siTop is itself a one-dimensional array. For example, you can refer to the second of the three subordinate one-dimensional arrays as myRecord02.siTop[2]. The structure item siNext declares a two-dimensional array, and you can refer to an element of that array by either of these syntaxes:
  // row 1, column 2.
  // the next syntax is strongly recommended
  // because it works with dynamic arrays as well
  myRecord02.siTop[1].siNext[2]

  // the next syntax is supported for compatibility
  // with VisualAge Generator
  myRecord02.siTop.siNext[1,2]

To clarify what area of memory is being referenced, let's consider how data in a multidimensional array is stored. In the current example, myRecord02 constitutes 120 bytes. The referenced area is divided into a one-dimensional array of three elements, each 40 bytes:

  siTop[1]     siTop[2]     siTop[3]

Each element of the one-dimensional array is further subdivided into an array of two elements, each 20 bytes, in the same area of memory:

  siNext[1,1] siNext[1,2] siNext[2,1] siNext[2,2] siNext[3,1] siNext[3,2]
A two-dimensional array is stored in row-major order. One implication is that if you initialize an array in a double while loop, you get better performance by processing the columns in one row before processing the columns in a second:
  // i, j, myTopOccurs, and myNextOccurs are data items; 
  // myRecord02 is a record; and
  // sysLib.size() returns the occurs value of a structure item.
  i = 1;
  j = 1;
  myTopOccurs = sysLib.size(myRecord02.siTop);
  myNextOccurs = sysLib.size(myRecord02.siTop.siNext);
  while (i <= myTopOccurs)
    while (j <= myNextOccurs)
      myRecord02.siTop.siNext[i,j] = "abc";
      j = j + 1;
    end
    i = i + 1;
  end

You must specify a value for each dimension of a multidimensional array. The reference myRecord02.siTop.siNext[1], for example, is not valid for a 2-dimensional array.

An example declaration of a 3-dimensional array is as follows:
  record myRecord03Part
    10 siTop[3];
      20 siNext[2];
        30 siLast CHAR(20)[5];
  end
If a record called myRecord03 is based on that part and if uniqueness rules are satisified, you can reference the last element in the array in any of the following ways:
  // each level is shown, and a subscript 
  // is on each level, as is recommended.
  myRecord03.siTop[3].siNext[2].siLast[5]

  // each level shown, and subscripts are on lower levels
  myRecord03.siTop.siNext[3,2].siLast[5]
  myRecord03.siTop.siNext[3][2].siLast[5]

  // each level is shown, and subscripts are on the lowest level
  myRecord03.siTop.siNext.siLast[3,2,5]
  myRecord03.siTop.siNext.siLast[3,2][5]
  myRecord03.siTop.siNext.siLast[3][2,5]
  myRecord03.siTop.siNext.siLast[3][2][5]

  // the container and the last level is shown, with subscripts
  myRecord03.siLast[3,2,5]
  myRecord03.siLast[3,2][5]
  myRecord03.siLast[3][2,5]
  myRecord03.siLast[3][2][5]

  // only the last level is shown, with subscripts
  siLast[3,2,5]
  siLast[3,2][5]
  siLast[3][2,5]
  siLast[3][2][5]

As indicated by the previous example, you reference an element of a multidimensional array by adding a bracketed set of subscripts, in any of various ways. In all cases, the first subscript refers to the first dimension, the second subscript refers to the second dimension, and so forth. Each subscript can vary from 1 to the occurs value of the related structure item, and a runtime error occurs if a subscript resolves to a number outside of that range.

First, consider the situation when subscripts are not involved:
  • You can specify a list that begins with the name of the variable and continues with the names of increasingly subordinate structure items, with each name separated from the next by a period, as in this example:
      myRecord03.siTop.siNext.siLast
  • You can specify the name of the variable, followed by a period, followed by the name of the lowest-level item of interest, as in this example:
      myRecord03.siLast
  • If the lowest-level item of interest is unique in a given name space, you can specify only that item, as in this example:
      siLast
Next, consider the rules for placing array subscripts:
  • You can specify a subscript at each level where one of several elements is valid, as in this example:
      myRecord03.siTop[3].siNext[2].siLast[5]
  • You can specify a series of subscripts at any level where one of several elements is valid, as in this example:
      myRecord03.siTop.siNext[3,2].siLast[5]
  • You can specify a series of subscripts at any level that is at or subordinate to a level where one of several elements is valid, as in this example:
      myRecord03.siTop.siNext.siLast[3,2,5]
  • An error occurs if you assign more subscripts than are appropriate at a given level. as in this example:
      // NOT valid
      myRecord03.siTop[3,2,5].siNext.siLast
  • You can isolate a subscript within a bracket or can display a series of subscripts, each separated from the next by a comma; or you can combine the two usages. The following examples are valid:
      myRecord03.siTop.siNext.siLast[3,2,5]
      myRecord03.siTop.siNext.siLast[3,2][5]
      myRecord03.siTop.siNext.siLast[3][2,5]
      myRecord03.siTop.siNext.siLast[3][2][5]
Feedback
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.