Attribute Update (GNAT Reference Manual)

### 4.74 Attribute Update ¶

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 unmodified. 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.