The ABC Code in LibSrc is often a good example of Clarion code. Some of it was written by DAB or Gavin. ABUTIL Field Pairs manages a Queue of 2 ANY’s:
FieldPairsQueue QUEUE,TYPE
Left ANY
Right ANY
END
FieldPairsClass CLASS,TYPE,MODULE('ABUTIL.CLW'),LINK('ABUTIL.CLW',_ABCLinkMode_),DLL(_ABCDllMode_)
List &FieldPairsQueue
AddPair PROCEDURE(*? Left,*? Right),VIRTUAL
...
Kill PROCEDURE
...
END
As you describe you see KILL does set all the ANYs to NULL. It does not FREE the QUEUE because DISPOSE does that for you. Note PUT was not done.
FieldPairsClass.Kill PROCEDURE
I UNSIGNED,AUTO
CODE
IF ~SELF.List &= NULL
LOOP I = 1 TO RECORDS(SELF.List)
GET(SELF.List,I)
SELF.List.Left &= NULL
SELF.List.Right &= NULL
END
DISPOSE(SELF.List)
END
RETURN
The help on ANY is a MUST READ if you are going to use them. There is coverage of ANY and Queue. You have to remember an ANY can be used for an &= Reference Assignment, or a = Xxx is a NEW.
Once an ANY variable in a QUEUE has been reference assigned a variable (AnyVar &= SomeVariable), another reference assignment statement will assign a new variable to the ANY. This means the previous “pointer” is disposed of and replaced by the new “pointer.” If the first reference has already been added to the QUEUE, then that entry will “point at” a “pointer” that no longer exists.
Therefore, Queue fields of type ANY must be set to NULLs by executing the CLEAR statement with the QUEUE record structure itself as parameter, i.e. the program must execute CLEAR(Queue), before setting new values of queue field of type ANY for the next ADD() or PUT(). This is because CLEAR for QUEUEs and GROUPs are not applied recursively to the data pointed at from fields of reference types. Therefore, CLEAR(queue) just sets fields of type ANY to NULLs without disposing of their internal data.
In addition, you need to reference assign a NULL to all queue fields of type ANY (Queue.AnyField &= NULL), prior to deleting the QUEUE entry, in order to avoid memory leaks.
Below you see before an ADD the CLEAR(Q) is done to deal with the ANY’s
FieldPairsClass.AddPair PROCEDURE (*? Left, *? Right)
CODE
? ASSERT(~(SELF.List &= NULL))
CLEAR(SELF.List)
SELF.List.Left &= Left
SELF.List.Right &= Right
ADD(SELF.List)
RETURN
I think Jeff Slarve wrote a CMag article on QUEUE and ANY. I have trouble searching the new Jira archive.