On 09/22/2015 03:46 AM, Robert Hanson wrote: > I think this is the essence of a deep copy: > > function deepCopy(a) { > switch (a.type) { > case "hash": > var b = {}; > for (var i = a.keys.length; i > 0; --i) { > var key = a.keys[i]; > b[key] = deepCopy(a[key]); > } > return b; > case "array": > var b = []; > for (var j = a.length; j > 0; --j) { > b[j] = deepCopy(a[j]); > } > return b; > default: > return a; > } > } > Thanks, Bob! It does work with my example.
So the major difference for scalar values is that the value is assigned as the return value of a function instead of directly with 'x=a' or 'x=@a'? When I used the result of the copy I observed an interference problem between local variables and other local or global variables: -------- Example Code ----------------- function deepCopy(a) { switch (a.type) { case "hash": var b = {}; for (var i = a.keys.length; i > 0; --i) { var key = a.keys[i]; b[key] = deepCopy(a[key]); } return b; case "array": var b = []; for (var j = a.length; j > 0; --j) { b[j] = deepCopy(a[j]); } return b; default: return a; } } function renumber(atomInfos) { for (var atomId in atomInfos) { atomInfos[atomId]..seqNum *= 10; } } function localTest(atomInfos, subsetKey) { for (var atomId in atomInfos) { var atomInfo = atomInfos[atomId]; var seqNum = atomInfo..seqNum; print "LOCALTEST: subsetKey=" + subsetKey + " atomId=" + atomId + " seqNum=" + seqNum; } } globalHash = [subsets: [subset1: [atomInfos: [atom1: [seqNum: 1], atom2: [seqNum: 2], atom3: [seqNum: 3] ] ], subset2: {} ] ]; filter = "[SELECT ** WHERE seqNum > 1]"; globalHash..subsets..subset2..atomInfos = deepCopy(getProperty(globalHash..subsets..subset1..atomInfos, filter)); renumber(globalHash..subsets..subset2..atomInfos); print "====== Subset 2 ==========="; print globalHash..subsets..subset2..atomInfos; print "====== Subset 1 ==========="; print globalHash..subsets..subset1..atomInfos for (var atomId in globalHash..subsets..subset2..atomInfos) { var atomInfo = globalHash..subsets..subset2..atomInfos[atomId]; var seqNum = atomInfo..seqNum; localTest(globalHash..subsets..subset1..atomInfos, "subset1"); print "GLOBALLOOP: subsetKey=subset2 atomId=" + atomId + " seqNum=" + seqNum; print atomInfo; } ----- Example output ------------- ====== Subset 2 =========== { "atom2" : { "seqNum" : 20 } "atom3" : { "seqNum" : 30 } } ====== Subset 1 =========== { "atom1" : { "seqNum" : 1 } "atom2" : { "seqNum" : 2 } "atom3" : { "seqNum" : 3 } } LOCALTEST: subsetKey=subset1 atomId=atom1 seqNum=1 LOCALTEST: subsetKey=subset1 atomId=atom2 seqNum=2 LOCALTEST: subsetKey=subset1 atomId=atom3 seqNum=3 GLOBALLOOP: subsetKey=subset2 atomId=atom3 seqNum=20 { "seqNum" : 20 } LOCALTEST: subsetKey=subset1 atomId=atom1 seqNum=1 LOCALTEST: subsetKey=subset1 atomId=atom2 seqNum=2 LOCALTEST: subsetKey=subset1 atomId=atom3 seqNum=3 GLOBALLOOP: subsetKey=subset2 atomId=atom3 seqNum=30 { "seqNum" : 30 } ---------------------------------- So the problem in the example is that the loop variable 'atomId' in the global loop is influenced by the local loop variable 'atomId' in the function 'localTest'. Before 'localTest' is called it is still ok, because 'seqNum' is ok which means that 'atomInfo' was assigned correctly. Even after calling 'localTest' the variable 'atomInfo' is still ok in the global loop. The same problem occurs if the loop variable is a global variable and/or the global loop is moved into a second function or both loops are moved into the same function: ---- Example Code 2 -------------- function mainLoop() { for (var atomId in globalHash..subsets..subset2..atomInfos) { var atomInfo = globalHash..subsets..subset2..atomInfos[atomId]; var seqNum = atomInfo..seqNum; for (var atomId in globalHash..subsets..subset1..atomInfos) { var atomInfo = globalHash..subsets..subset1..atomInfos[atomId]; var seqNum = atomInfo..seqNum; print "LOCALTEST: subsetKey=subset1 atomId=" + atomId + " seqNum=" + seqNum; } print "MAINLOOP: subsetKey=subset2 atomId=" + atomId + " seqNum=" + seqNum; print atomInfo; } } ---- Example Output 2 ------------ LOCALTEST: subsetKey=subset1 atomId=atom1 seqNum=1 LOCALTEST: subsetKey=subset1 atomId=atom2 seqNum=2 LOCALTEST: subsetKey=subset1 atomId=atom3 seqNum=3 MAINLOOP: subsetKey=subset2 atomId=atom3 seqNum=20 { "seqNum" : 20 } LOCALTEST: subsetKey=subset1 atomId=atom1 seqNum=1 LOCALTEST: subsetKey=subset1 atomId=atom2 seqNum=2 LOCALTEST: subsetKey=subset1 atomId=atom3 seqNum=3 MAINLOOP: subsetKey=subset2 atomId=atom3 seqNum=30 { "seqNum" : 30 } ---------------------------------- There might be other interference problems but it is quite difficult for me to pin them down within my rather complex code (about 50 functions with about 5000 lines of Jmol script). The major problem here is to separate my own programming bugs from Jmol internal bugs. Regards, Rolf -- Rolf Huehne Postdoc Leibniz Institute for Age Research - Fritz Lipmann Institute (FLI) Beutenbergstrasse 11 07745 Jena, Germany Phone: +49 3641 65 6205 Fax: +49 3641 65 6210 E-Mail: rhue...@fli-leibniz.de Website: http://www.fli-leibniz.de Scientific Director: Prof. Dr. K. Lenhard Rudolph Head of Administration: Dr. Daniele Barthel Chairman of Board of Trustees: Dennys Klein VAT No: DE 153 925 464 Register of Associations: No. 230296, Amtsgericht Jena Tax Number: 162/141/08228 ------------------------------------------------------------------------------ _______________________________________________ Jmol-users mailing list Jmol-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jmol-users