Error Messages/40465

Error Message

An attempt was made to assign to a slice of a non-local object or an index. Slice assignment can only be applied to change the slice of a local value.

Description

Slice assignment refers to an assignment which a slice or subscript on the left hand side of the := operator, such as

a[J='x'] := 10;

or

a[@J=1] := 10

You can only apply this to a local value. So in the previous examples, a would be a local declared using Local..Do, or it might be an evaluated parameter in a UDF. You cannot use slice assignment to change a slice of a global variable (or any other object type), even if that variable is already defined as a Table. If you attempt to do so, this error results. So if Va1

Va1[ J = 'x' ] := 10 {Results in this error}

Since a LocalAlias also names a global object, the same would be true if you attempt to slice-assign to a local alias identifier, even though the identifier has only a local lexical scope, e.g.,

LocalAlias v := Handle(Va1);
v[ J = 'x' ] := 10 {Results in this error}

Prior to Analytica 6.0, there was a bug in which this latter case failed to generate this error. Instead, no change to the global object , and the local's value converted from an alias into an array. So if you are seeing this error after moving to Analytica 6.0, but didn't see if previously, this may be why.

But how to I assign to a global slice?

Slice-assigning to a global variable can be done in three steps: (1) Copy the value to a local value, (2) Slice assign to the local value, and (3) Copy the value back to the global. These are shown here for the global variable Va1.

Local tmp := Va1;
tmp[ J = 'x' ] := 10;
Va1 := tmp

This uses the mid value of Va1, then sets Va1's Definition to a Table. This pattern preserves cell controls as long as the value assigned is a value produced by the control, but will replace more general expressions with a literal value.

Steps 1 and 3 in this pattern are extremely computationally expensive. The third step in particular causes all downstream results to be invalidated and any open UI windows to have to resynchronize. If your code will eventually need to make more than one slice update, you should do all your updates between steps 1 and 3. This inefficiency is part of the reason why slice assignment to a global is not directly allowed -- it encourages you to do all your updates between steps 1 and 3 to amortize those costs.

If you have an algorithm that requires some sort of in-memory side-effect, a local value capture can provide an efficient and elegant method for doing so (but this is an experimental feature as of Analytica 6.0).

See also

Comments


You are not allowed to post comments.