Ada Programming/Attributes/'Update

Description

edit

The Update attribute creates a copy of an array or record value with one or more modified components. The syntax is:

PREFIX'Update ( RECORD_COMPONENT_ASSOCIATION_LIST )
PREFIX'Update ( ARRAY_COMPONENT_ASSOCIATION {, ARRAY_COMPONENT_ASSOCIATION } )
PREFIX'Update ( MULTIDIMENSIONAL_ARRAY_COMPONENT_ASSOCIATION
                {, MULTIDIMENSIONAL_ARRAY_COMPONENT_ASSOCIATION } )

MULTIDIMENSIONAL_ARRAY_COMPONENT_ASSOCIATION ::= INDEX_EXPRESSION_LIST_LIST => EXPRESSION
INDEX_EXPRESSION_LIST_LIST                   ::= INDEX_EXPRESSION_LIST {| INDEX_EXPRESSION_LIST }
INDEX_EXPRESSION_LIST                        ::= ( EXPRESSION {, EXPRESSION } )

where PREFIX is the name of an array or record object, the association list in parentheses does not contain an others choice and the box symbol <> may not appear in any expression. The effect is to yield a copy of the array or record value which is unchanged apart from the components mentioned in the association list, which are changed to the indicated value. The original value of the array or record value is not affected. For example:

type Arr is Array (1 .. 5) of Integer;
...
Avar1 : Arr := (1,2,3,4,5);
Avar2 : Arr := Avar1'Update (2 => 10, 3 .. 4 => 20);

yields a value for Avar2 of 1,10,20,20,5 with Avar1 begin unmodified. Similarly:

type Rec is A, B, C : Integer;
...
Rvar1 : Rec := (A => 1, B => 2, C => 3);
Rvar2 : Rec := Rvar1'Update (B => 20);

yields a value for Rvar2 of (A => 1, B => 20, C => 3), with Rvar1 being unmodifed. Note that the value of the attribute reference is computed completely before it is used. This means that if you write:

Avar1 := Avar1'Update (1 => 10, 2 => Function_Call);

then the value of Avar1 is not modified if Function_Call raises an exception, unlike the effect of a series of direct assignments to elements of Avar1. In general this requires that two extra complete copies of the object are required, which should be kept in mind when considering efficiency.

The Update attribute cannot be applied to prefixes of a limited type, and cannot reference discriminants in the case of a record type. The accessibility level of an Update attribute result object is defined as for an aggregate.

In the record case, no component can be mentioned more than once. In the array case, two overlapping ranges can appear in the association list, in which case the modifications are processed left to right.

Multi-dimensional arrays can be modified, as shown by this example:

A : array (1 .. 10, 1 .. 10) of Integer;
..
A := A'Update ((1, 2) => 20, (3, 4) => 30);

which changes element (1,2) to 20 and (3,4) to 30.