[Harmony proxies] Revisiting the forwarding proxy pattern

Tom Van Cutsem tomvc.be at gmail.com
Tue Apr 5 01:49:05 PDT 2011


2011/3/24 Tom Van Cutsem <tomvc.be at 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))
      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;
  },

(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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110405/88f36dc0/attachment-0001.html>


More information about the es-discuss mailing list