indirect <ident> { => <value> }
Declare (and optionally assign) an indirect identifier. Indirect (also known as generic) identifiers are pointers to other identifiers.
<ident>
The name of the identifier. Unlike other identifier declarations, a name
without an atable prefix will create a local identifier, thus ignoring any
scope creation rules.
<value>
An expression yielding another identifer, which must exist.
None
If not given a value, the identifier is initialized to null, i.e. it will point to nothing. To test whether an indirect identifier, say ptr, is valid, i.e. it points to something valid, use the exist function, e.g. if (exist(ptr)).
Once assigned, an indirect identifier may be used wherever the identifier to
which it points (known as its target) can be used.
All operations, including value assignments, done to the indirect identifier
will be done to its target. This includes the delid
command which will delete its target, thereby nullifying the indirect identifier.
If the target is deleted explicity, this will also nullify all indirect identifiers
which point to it.
Using delid on a null indirect identifier will do nothing. To delete the indirect identifier itself, use delid -ind.
An indirect identifier can be redirected to point to another target by using the => operator. Such an operation will have no effect on the indirect identifiers's original target
Indirect identifier functions are permitted, to allow a function to return a pointer to a complex object, see below for an example.
Indirect identifiers may be members of structures.
Values of indirect identifiers (their targets) are not stored when identifiers are saved to atable files (by an unload command). When the atable is re-loaded from file, all re-loaded indirect identifiers will be null.
Create a structure array and manipulate it via a pointer.
~myatable.thing_t things[10];# Create an array of structures indirect ptr => things;# Note the use of => ptr[6].some_member = 5;# This will assign a value to a member of the 6th element of things delid ptr[5];# This will remove the 5th element of things tell ptr.alength;# This should display the value 9 delid ptr;# This will remove things and nullify ptr delid ptr;# This will remove ptr because it is now null
Use an indirect function to pass a structure value.
indirect_function getObject { ~myatable.thing_t ~myatable.thing;# Create a structure object # The return value must not point to a local identifier because # it will disappear when the function execution is complete. # Therefore the return value must always be a persistent identifier, i.e. # one resident in an atable funcval => ~myatable.thing } indirect ptr => getObject() list ptr;# This will list the contents of ~myatable.thing
Test whether an indirect identifier is valid (i.e. not null)
indirect ptr => getObject() unless (exist(ptr)) ! It is null