Hi Peter, Cannon Smith has written a component OBJ_Module, free for the community. It's amazingly useful !
I have selected this from read me that explains the behavior you have seen //-------------------------------------- // Reference Counting vs Copying //-------------------------------------- //Native 4D objects are reference counted. This is a good thing because it increases speed and saves on memory for //typical operations. But it can also be a bit confusing if you're not used to it. With ref counting, when an object //is assigned to another object (including when being passed as a parameter), only the reference is passed. Think of //it like a pointer. For example, if you have an object $oObject, you might do this: $oDuplicate:=$oObject. If it was //like most other 4D types we are used to, there would now be two objects and if we made a change to $oObject it would //not affect $oDuplicate. But this is not the case with objects. $oObject and $oDuplicate both point to the same actual //object in memory. Making a change to $oObject effectively changes $oDuplicate as well. Often you want to use objects //this way (ref counting), but sometimes you want an actual copy and 4D provides a way to do this with OB Copy. //This module attempts to make this a bit more natural by doing the most likely thing by default, but providing a way //to do the other thing as an option for the methods where this makes sense. For example, OBJ_Set_Object and //OBJ_Get_Object both have an option to set/get the object by reference or by copying. You can download here http://files.synergyfarmsolutions.com/4DNug/OBJ_Module.zip <http://files.synergyfarmsolutions.com/4DNug/OBJ_Module.zip> Cherry on the cake, you can use dot notation. 0,02 €, Bernard Escaich > Le 29 oct. 2016 à 13:28, Peter Jakobsson <[email protected]> a écrit : > > Hi > > Apologies if this has been discussed before - I haven’t kept up with all > threads on the topic but noticed this interesting behaviour just now. I > thought it was a bug at first but now I see it’s a feature, albeit a slightly > un-intuitive one based on what we’re used to. > > If I do this…….. > > =================== CODE BLOCK 1 ==================== > > ARRAY TEXT($arrayTEXT;0) > > $myName:=“Ian” > APPEND TO ARRAY($arrayTEXT;$myName) > > $myName:=“Sandra” > APPEND TO ARRAY($arrayTEXT;$myName) > > $myName:=“george” > APPEND TO ARRAY($arrayTEXT;$myName) > > ==================================================== > > ….then each array element will contain a distinct value. i.e. {1}=“Ian" > {2}=“Sandra” {3}=“George” > > > On the other hand, if I do this… > =================== CODE BLOCK 2 ==================== > > ARRAY OBJECT($arrOBJECTS;0) > > $myObject=JSON Parse("{}”) (Create an empty object) > > OB SET($myObject ;"myName”;”Ian”) > APPEND TO ARRAY($arrOBJECTS;$myObject) > > OB SET($myObject ;"myName”;”Sandra”) > APPEND TO ARRAY($arrOBJECTS;$myObject) > > OB SET($myObject ;"myName”;”George”) > APPEND TO ARRAY($arrOBJECTS;$myObject) > ==================================================== > > …then simply assigning $myObject assigns EVERY value in the array. i.e. my > array now contains [1]=“George” [2]=“George” [3]=“George” > > So in this respect, objects are more like pointers than Blobs because you’re > just passing around a reference to a single memory space. > > However, what’s even weirder is if we now change $arrOBJECTS to a process > array but leave $myObject as a local and allow it to go out of scope. Can > anybody predict what will happen now ? I couldn’t - just had to try it :-) > > In fact what occurs is this (calls made in the parent procedure once CODE > BLOCK 2 drops back into caller): > > =================== CODE BLOCK 3 ==================== > > OB SET(arrOBJECTS{1};"myName";"Mickey”) ` ALL elements now contain [1]=“ > Mickey” [2]=“ Mickey” [3]=“ Mickey” > OB SET(arrOBJECTS{2};"myName";"Goofy") ` ALL elements now contain [1]=“ > Goofy” [2]=“ Goofy” [3]=“ Goofy” > OB SET(arrOBJECTS{3};"myName";"Pluto") ` ALL elements now contain [1]=“ > Pluto” [2]=“ Pluto” [3]=“ Pluto” > ==================================================== > > So by assigning a key-value in one element of the object array, I’m > potentially assigning them all. I have to know myself whether they all > reference the same object or distinct objects. Further, even though my > original local went out of scope, the actual object “space” that it was > referencing hasn’t. 4D seems to realise that the object space is referenced > by a variable somewhere which remains in scope after the instantiating method > has finished executing. > > This is very clever of 4D IMO. There must be some memory management > gymnastics going on under the hood to make this work so consistently with > other variable types. Note the difference with pointer arrays - when a > process level pointer array contains a pointer to a local variable that’s out > of scope, the debugger reports its name ok but its value is “UNDEFINED”. On > the other hand, when an process level object array contains an object > reference that was originally held in a local variable thats now dropped out > of scope, the object array CONTINUES to hold a reference to the underlying > data and you can continue to do OB Get on it. > > The question is, what does 4D do to object spaces that are only referenced by > locals ? I imagine that to avoid memory leaks, it must keep track of all > references and delete the object space when all references have dropped out > of scope. Conversely it seems to imply that if we reference an object with a > process variable then the object space will never be deleted until 4D quits = > another “Watcha” ! > > Hope this is of interest to other observers and sorry for the “DUH” factor if > you already understood this as implicitly as pouring a cup of tea ! :) > > Regards > > Peter > > ********************************************************************** > 4D Internet Users Group (4D iNUG) > FAQ: http://lists.4d.com/faqnug.html > Archive: http://lists.4d.com/archives.html > Options: http://lists.4d.com/mailman/options/4d_tech > Unsub: mailto:[email protected] > ********************************************************************** ********************************************************************** 4D Internet Users Group (4D iNUG) FAQ: http://lists.4d.com/faqnug.html Archive: http://lists.4d.com/archives.html Options: http://lists.4d.com/mailman/options/4d_tech Unsub: mailto:[email protected] **********************************************************************

