> (reposting source code from previous message as plain text)
>
>   fix: function() {
>     // As long as target is not frozen, the proxy won't allow itself
> to be fixed
>     if (!Object.isFrozen(this.target))
>       return undefined;
>     var props = {};
>     var handler = this;
>     Object.getOwnPropertyNames(this.target).forEach(function (name) {
>       var desc = Object.getOwnPropertyDescriptor(this.target, name);
>       // turn descriptor into a trapping accessor property
>       props[name] = {
>                 get: function( ) { return handler.get(this, name); },
>                 set: function(v) { return handler.set(this, name, v); },
>          enumerable: desc.enumerable,
>        configurable: desc.configurable
>       };
>     });
>     return props;
>   },
I really love this.
The Object.isFrozen call is unfortunate but necessary since we only have
one trap for the three extension-preventing methods. Throwing a
TypeError on Object.preventExtension(proxy) because the target isn't
frozen sounds a bit wrong to me though. Maybe that something could be
passed as an argument to fix in order to discriminate which call happened.
>From what I understand, all interaction that set [[Extensible]] to false
will end up calling the fix trap (+ TypeError||become) for proxies. As
we can't know now what will later be added to the language to do that,
it may be a good thing to be able to discriminate the origin of the fix
trap call.

Also, an idea for so-called "forwarding" proxies could be that the proxy
forwards preventExtension/seal/freeze calls to the target too. It could
be a nice thing if target is itself a proxy.

Combining the ideas, we could have something like:

fix: function(type){
  if (type === Proxy.PREVENT_EXTENSION) // syntax example
    Object.preventExtension(this.target);
// a switch case could be a good idea too
// same code than you starting at "var props"
}

Even if not forwarding the call, it could allow better granularity than
Object.isFrozen.

Now that I think about it, if forwarding Object.seal/freeze calls, the
target and previously-proxy would act the same with very few exception.
The non-configurability of all properties ensure that both keep the
exact same property set will remain (non-deletable) with same
[[enumerable]] for each (non-configurable). Your get/set method ensure
that property access react the same in both objects. Besides
Object.getOwnPropertyDescriptor and their identity, I can't think of any
way to distinguish them.

David


>
> 2011/4/5 Tom Van Cutsem <tomvc.be <http://tomvc.be>@gmail.com
> <http://gmail.com>>
>
>
>
>     2011/3/24 Tom Van Cutsem <tomvc.be <http://tomvc.be>@gmail.com
>     <http://gmail.com>>
>
>             I just wanted to discuss forwarding patterns when it comes
>             to inheritance because the current forwarding proxy
>             doesn't discuss the point and when it comes to fixing the
>             proxy, surprising results could arise (since inheritance
>             changes because target and proxy prototypes aren't the
>             same object). Actually, if forwarding handlers were part
>             of the spec, would it make sense to fix them? shouldn't
>             "return undefined;" be the default fix trap?
>             
> (http://wiki.ecmascript.org/doku.php?id=harmony:proxy_defaulthandler)
>             (just the default, of course, the user can change it anytime)
>
>
>         "return undefined;" is definitely a sensible default. The
>         current default goes a bit further: if the target object is
>         frozen, it will fix the forwarding proxy in such a way that
>         the proxy and the target have the exact same own properties. I
>         don't recall us giving much thought to this default
>         implementation though. In fact, I think it's broken since it
>         doesn't take into account any custom proxying behavior. As an
>         example: say I implement a "logging" proxy that just logs all
>         operations performed on "target". It's sensible to extend the
>         default forwarding handler to do this. Now, if both the target
>         and the proxy are frozen, the logging behavior will be lost!
>         The solution is for my logging proxy to override the fix()
>         trap and perhaps return a property descriptor map that
>         replaces each own property in target with a wrapped version
>         that still performs the logging. If fix() returns "undefined"
>         by default, the above scenario would lead to an exception
>         instead of silently doing the wrong thing.
>
>
>     I've been thinking about the default implementation of the |fix()|
>     trap. Another sensible default, other than just returning
>     undefined unconditionally, is to freeze the proxy's structure, but
>     to replace all original properties with accessor properties that
>     still trigger the proxy's handler. A fixed forwarding proxy can
>     then still intercept property access, but other than its get and
>     set traps, none of its other traps would be called anymore:
>
>       fix:function(){
>         // As long as target is not frozen, the proxy won't allow
>     itself to be fixed
>         if(!Object.isFrozen(this.target))
>           returnundefined;
>         varprops ={};
>         varhandler =this;
>         Object.getOwnPropertyNames(this.target).forEach(function(name){
>           vardesc =Object.getOwnPropertyDescriptor(this.target,name);
>           // turn descriptor into a trapping accessor property
>           props[name]={
>                     get:function(){returnhandler.get(this,name);},
>                     set:function(v){returnhandler.set(this,name,v);},
>              enumerable:desc.enumerable,
>            configurable:desc.configurable
>           };
>         });
>         returnprops;
>       },
>
>
>     (full forwarding handler available at
>     
> <http://code.google.com/p/es-lab/source/browse/trunk/src/proxies/forwardingHandler.js>)
>
>     (untested because fix() isn't yet supported in fx4, see
>     <https://bugzilla.mozilla.org/show_bug.cgi?id=600677>)
>
>     Cheers,
>     Tom
>
>

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to