Revision: 4180
          http://vexi.svn.sourceforge.net/vexi/?rev=4180&view=rev
Author:   clrg
Date:     2011-07-08 01:45:36 +0000 (Fri, 08 Jul 2011)

Log Message:
-----------
Fix.  Cloning documentation was all wrong.

Modified Paths:
--------------
    trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JS.jpp

Modified: trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JS.jpp
===================================================================
--- trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JS.jpp   2011-07-06 
17:24:17 UTC (rev 4179)
+++ trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JS.jpp   2011-07-08 
01:45:36 UTC (rev 4180)
@@ -154,25 +154,83 @@
 /*@PAGE(concept=Cloning)
  * 
  * <p>A clone is an object that shares the properties of the object from which 
it was cloned, but
- * can be modified using traps that do not impact upon the original object.</p>
+ * is modified independently from the original object, with changes made to 
the clone never
+ * affecting the original.</p>
  * 
- * <p>Clones can be created using the <code>vexi.js.clone()</code> 
function.</p>
+ * <p>A clone of an object is essentially a JS object wrapping the original 
object &mdash; the
+ * clonee.  The clone is initially identical to the clonee but is not the same 
object.  Traps
+ * cascade to traps on the clonee, puts act on the clone, and reads fallback 
to the clonee only
+ * when the property is not in the keyset of the clone.</p>
  * 
+ * <h3>Creating Clones</h3>
+ * 
+ * <p>Clones are created using the <code>vexi.js.clone()</code> function.</p>
+ * 
  * <p>You may get the original object using <code>vexi.js.unclone()</code> 
function.  It will
  * always get the original object and never return a clone.</p>
  * 
+ * <p>You may created multiple clones of an object.  You may create clones of 
clones.  Clones can
+ * be created and discarded without affecting the original object directly.</p>
+ * 
+ * <p>A clone is a different object to its clonee, so the following is always 
true:</p>
+ * 
+ * <pre> vexi.js.clone(clonee) != clonee;</pre>
+ * 
  * <h3>Clone Behaviour</h3>
  * 
- * <p>A clone of an object is initially identical to the object it has cloned, 
the clonee, and puts
- * and reads on the clone will act upon the clonee, but they are not the same 
object.  Traps placed
- * on the clone are not placed on the clonee.  That is, puts and reads on the 
clone will act upon
- * the clonee unless otherwise intercepted by non-cascading traps on the 
clone.</p>
+ * <p>General behaviour:</p>
  * 
+ * <ul>
+ * <li>
+ * <p><b><i>traps</i></b></p>
+ * <p>Traps are assigned and removed only from the clonee.  Traps on the
+ * clone are called in order of assignment, before cascading down to the
+ * trapchain assigned to the clonee.  Traps are always called before any
+ * puts to the clone or reads from the clone or clonee.</p>
+ * <p>Traps on the clone are not visible to the clonee, so puts or reads
+ * made directly on the clonee will never invoke traps on the clone.</p>
+ * </li>
+ * 
+ * <li>
+ * <p><b><i>puts</i></b></p>
+ * <p>Puts only ever affect the clone, and will add to the keyset of the clone
+ * just as with a normal JS object.</p>
+ * <p>Puts directly on the clonee do not affect the keyset of the clone.</p>
+ * </li>
+ * 
+ * <li>
+ * <p><b><i>reads</i></b></p>
+ * <p>Reads only fall back to the clonee in the event that the property
+ * key does not exist in the keyset on the clone.</p>
+ * </li>
+ * </ul>
+ * 
+ * <p>Keyword specific behaviour:</p>
+ * 
+ * <ul>
+ * <li>
+ * <p><b>keysof</b></p>
+ * <p>Returns a combined keyset of the clone and the clonee, with the
+ * exception that 'remove' will only ever remove keys from the clone.
+ * if the property is only in the keyset of the clonee, this will cause
+ * an exception.</p>
+ * </li>
+ * 
+ * <li>
+ * <p><b>typeof</b></p>
+ * <p>A clone will identify itself as the same type as the clonee.</p>
+ * </li>
+ * 
+ * <li>
+ * <p><b>instanceof</b></p>
+ * <p>A clone is an Object in addition to being the same type as the 
clonee.</p>
+ * </li>
+ * </ul>
+ * 
  * <p>Consider:</p>
  * 
  * <pre> var clonee = { a:3, b:5 };
  * var clone = vexi.js.clone(clonee);
- * var z;
  * 
  * // true
  * 3 == clonee.a == clone.a;
@@ -181,15 +239,13 @@
  * clone.a = 2;
  * 2 == clonee.a == clone.a;
  * 
- * // still true after put to clonee
+ * // put to clonee.a alters this
  * clonee.a = 1;
- * 1 == clonee.a == clone.a;
+ * 1 == clone.a;
+ * 2 == clonee.a;
+ * clonee.a != clone.a;
  * 
- * // these reads are equivalent
- * z = clone.a;
- * z = clonee.a;
- * 
- * // non-cascading traps
+ * // non-cascading traps on clone do not affect clonee
  * clone.b ++= function(v) { return; }
  * clone.b ++= function() { return 0; }
  * 
@@ -198,16 +254,15 @@
  * clonee.b = 2; // clone.b == 0, clonee.b == 2
  * 
  * // these reads are not equivalent
- * z = clone.b;  // z==0
- * z = clonee.b; // z==2</pre>
+ * var r1 = clone.b;  // r1==0
+ * var r2 = clonee.b; // r2==2
  * 
- * <p>You may created multiple clones of an object.  You may create clones of 
clones.  Clones can
- * be created and discarded without affecting the original object directly.</p>
- * 
- * <p>A clone is a different object to its clonee, so the following is always 
true:</p>
- * 
- * <pre>
- * vexi.js.clone(clonee) != clonee</pre>
+ * // write trap on clonee affects clone put
+ * clonee.c ++= function(v) { cascade = 2*v; }
+ * clone.c = 2;
+ * clone.c == 4; // true
+ * clonee.c = 3;
+ * clonee.c == 6; // true</pre>
  */
 
 /** The minimum set of functionality required for objects which are 
manipulated by JavaScript */
@@ -349,25 +404,31 @@
         }
     }
 
-    /** A JS.Clone of a JS is identical to the object it has cloned, the 
clonee,
-     *  except that traps placed on it are not placed on the clonee. */
+    /** 
+     *  A JS.Clone of a JS is a mirror of the object it has cloned, the clonee,
+     *  however modifications of the clone are not made to the clonee. That is
+     *  property puts and trap assignments on the clone do not affect the 
clonee,
+     *  it is impossible to directly modify the clonee by modifying the clone.
+     **/
     public static class Clone extends JS.Obj {
+        
+        // The JS that was cloned
         protected final Cloneable clonee;
+        
         public Clone(JS clonee) throws JSExn {
             if (!(clonee instanceof Cloneable)) {
                 throw new JSExn(clonee.getClass().getName() + " does not 
implement cloneable");
             }
             this.clonee = (Cloneable)clonee;
         }
-        // Non-Trap methods forward to the clonee 
-        public JS unclone() { return clonee.unclone(); }
+        
         public Keys keys() throws JSExn { 
                final Set ourkeys = keySet();
                final Set allkeys = new HashSet(ourkeys);
                JS c = this.clonee;
-               while(true) {
+               while (true) {
                        allkeys.addAll(c.keySet());
-                       if(c instanceof Clone) c = ((Clone)c).clonee;
+                       if (c instanceof Clone) c = ((Clone)c).clonee;
                        else break;
                }
                
@@ -389,11 +450,11 @@
                     };
                 }
                 protected JS remove(JS key) throws JSExn {
-                       if(ourkeys.contains(key)){
+                       if (ourkeys.contains(key)) {
                         JS r = Clone.this.get(key);
                         Clone.this.remove(key);
                         return r;
-                       }else if(allkeys.contains(key)){
+                       } else if (allkeys.contains(key)) {
                                throw new JSExn("Cannot remove key from clonee: 
" +key);
                        }
                     return null;
@@ -404,28 +465,35 @@
                 public int size() throws JSExn { return allkeys.size(); }
             };
         }
-        public JS callMethod(JS this_, JS method, JS[] args) throws JSExn {
-            return clonee.callMethod(this_, method, args);
-        }
+        
+        /** gets a property of the given key, falling back to the cloned 
object */
         public JS get(JS k) throws JSExn { 
-               if(hasKey(k)) return super.get(k);
+               if (hasKey(k)) return super.get(k);
                return clonee.get(k); 
         }
+        
+        /** put directly on the given key, but never to the cloned object */
         public void put(JS k, JS v) throws JSExn { 
                super.put(k, v); 
         }
-        public String[] getFormalArgs() { return clonee.getFormalArgs(); }
-        public int callType() { return clonee.callType(); }
-        public String coerceToString() { return clonee.coerceToString(); }
-        public JS type() { return clonee.type(); }
         
         /** gets a trap for the given key, falling back to the cloned object */
         public Trap getTrap(JS key) { 
             Trap t = super.getTrap(key);
             return t!=null ? t : clonee.getTrap(key);
         }
+        
+        // Non-Trap/-Property methods forward to the clonee
+        public JS callMethod(JS this_, JS method, JS[] args) throws JSExn {
+            return clonee.callMethod(this_, method, args);
+        } 
+        public JS unclone() { return clonee.unclone(); }
+        public String[] getFormalArgs() { return clonee.getFormalArgs(); }
+        public int callType() { return clonee.callType(); }
+        public String coerceToString() { return clonee.coerceToString(); }
+        public JS type() { return clonee.type(); }
         public boolean instanceOf(JS type) {
-               if(super.instanceOf(type)) return true;
+               if (super.instanceOf(type)) return true;
                return clonee.instanceOf(type);
         }
     }
@@ -447,8 +515,8 @@
             }
         };
         static public ConstructorList base = new 
ConstructorList(Constructor,null);
-         
         
+        
         protected ConstructorList constructors = null;
         // a map of values against properties stored on this object
         private Map props = null;
@@ -489,10 +557,10 @@
             }
             if (traps!=null && traps.size()>0) {
                Iterator I = traps.keySet().iterator();
-               while(I.hasNext()){
+               while (I.hasNext()) {
                        JS key = (JS)I.next();
                        Trap t = (Trap) traps.get(key);
-                       if(t.findRead()!=null)
+                       if (t.findRead()!=null)
                                throw new JSExn("cannot deepcopy object with 
read traps: "+JSU.toString(key));
                }
             }
@@ -694,7 +762,6 @@
                 }
             }
         }
-
         
         /** <p>Returns obj$xxxxxxxx where xxxxxxxx is the hashcode in hex.</p> 
          *  <p>Uniqueness (so can act as a keys in a map) and some human 
readability are 
@@ -702,7 +769,6 @@
          *  <p>REMARK - the hash should be unique, though its not guaranteed 
by Java</p> */
         public String coerceToString() { return "obj$" + 
Integer.toHexString(hashCode()); }
 
-
         public Map getPropsMap() { return traps; }
         public Map getTrapsMap() { return props; }
     }
@@ -710,10 +776,10 @@
     /** An implementation of JS that supports a meta trap on all properties */
     public static class Proxy extends Obj {
         static public JS Constructor = new JS.Constructor("Proxy"){
-             public JS new_(JS[] args) throws JSExn { 
-                 return new JS.Proxy();
-             }
-         };
+            public JS new_(JS[] args) throws JSExn { 
+                return new JS.Proxy();
+            }
+        };
         
         Trap propertiesTrap = null;
         public JS get(JS key) throws JSExn {


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
Vexi-svn mailing list
Vexi-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to