Le 03/12/2012 16:38, Mark S. Miller a écrit :
What eternal[1] invariant does this bypass?

[1] https://mail.mozilla.org/pipermail/es-discuss/2011-May/014150.html
Apparently none... Yet, additionally to the last case I showed, there is also:

    var p = new Proxy({a:1}, {
        isExtensible: function(target, action){
            var v = action();
            Object.preventExtensions(target);
        }
    })

    // real life-like code?
    if(Object.isExtensible(target)){
        Object.defineProperty(target, 'b', {value: 37}); // throws
    }

I agree it's not an eternal invariant, but it's quite surprising.
[cc'ing Tom to make sure he reads this part]
Arguably, the isExtensible, seal and freeze trap could have no "action" and just forward to the target. That's what the current invariant enforcement suggests anyway ("Invariant check: check whether the boolean trap result is equal to isFrozen(target), isSealed(target) or isExtensible(target)"). This applies to current proxies actually. Maybe their return value could just be ignored. Trap authors have all the information they need with the trap arguments to decide whether they want to throw. For the rest, the operation can just be forwarded to the target (which it has to for invariant check already).


Proxies-with-action have this weird taste of "one-move ahead"; like if they could run what they're expected and then play a bit more of the game before actually showing their before-last move. It makes sense they do not violate eternal invariants

Although not rigorously necessary when it comes to the very minimalistic eternal invariants, the current proxies provides some guarantees by design which are nice both for whoever writes handlers and whoever manipulates proxies.

Unrelated, but I think that custom property descriptor attributes are lost with action-proxies. I'm not sure yet what is a good way to recover them.

David

On Mon, Dec 3, 2012 at 3:33 AM, David Bruant <bruan...@gmail.com> wrote:
Le 03/12/2012 00:06, David Bruant a écrit :

The call to action performs
the original operation on target and remembers the result. After the
trap returns, the proxy returns the remembered result of action.
     target = {a:1};
     var p = new Proxy(target, {
         get: function(target, name, action){
             var v = action();
             target[name] = 2;
         }
     })

     p.a; // ?

If p.a is 1 because the call to "action" remembered the "1", then the
target and the proxy look awkwardly desynchronized. To know what's being
returned from the trap, one needs to remember when the action is being
called which makes writing traps harder I feel. With the current design,
looking at the return statements is enough.
If p.a is 2, I don't understand the point of "action". Or at least, I
don't see how it's better than just calling Reflect[trap].
I've found much MUCH worse:


     target = {a:1};
     var p = new Proxy(target, {
         get: function(target, name, action){
             var v = action();
             Object.defineProperty(target, name, {value:2, configurable:
false, writable:false})
         }
     })

     p.a; // 1 ?

In that case, the mechanism used to bypass invariant checking is a way to
bypass invariants entirely.


David
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to