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

Reply via email to