Converting an existing object to a proxy

Tom Van Cutsem tomvc.be at gmail.com
Fri May 27 02:45:27 PDT 2011


>
> I tend to agree with David about having a separate observable API, if that
> is indeed the driving use case. That API can be very similar to the Proxy
> API though. Racket's "chaperones" come to mind: a chaperone is a strictly
> less powerful kind of proxy, one that is not allowed to arbitrarily change
> the result of the original operation (and IIRC, a chaperone also cannot stop
> the original operation from taking place on the target object).
>

Spoke too soon: from <
http://web.mit.edu/drracket_v501/share/racket/doc/reference/chaperones.html>
I learn that chaperones can throw exceptions, and thus presumably abort an
intercepted operation early. Still, the idea of a "tamed" kind of proxy is
worth exploring.


>
> Cheers,
> Tom
>
> 2011/5/27 David Bruant <david.bruant at labri.fr>
>
>>  Le 27/05/2011 04:13, Mark S. Miller a écrit :
>>
>> On Thu, May 26, 2011 at 5:04 PM, Cormac Flanagan <cormac at cs.ucsc.edu>wrote:
>>
>>> [documenting/expanding some ideas briefly discussed at today's meeting]
>>>
>>> The current proxy proposal has a method to create a new proxy:
>>>
>>> var proxy = Proxy.create(handler, proto);
>>>
>>> We could extend this proposal to allow an existing object to be
>>> converted to a proxy, via:
>>>
>>> var proxy = Proxy.createFrom(object, handler, proto);
>>>
>>  I am surprised by this proposal since a design goal of proxies was to
>> not be able to turn existing objects into proxies.
>> 4th "driving force" of the proxy proposal:
>> "security: avoid enabling arbitrary ES objects to be able to intercept the
>> properties of another object"
>>
>> The API itself (Proxy.create, Proxy.createFunction) seems to have been
>> design with this in mind.
>>
>>
>>
>>
>>> Here, the return value 'proxy' is the same address as the argument
>>> 'object'.
>>> The original object thus becomes a proxy. Any state of the original
>>> object
>>> is discarded.
>>>
>>  The notion of object "state" is not defined anywhere in the ES5 spec.
>> What is your definition of an "object state" ?
>>
>>
>>
>>> This extension appears to support additional applications, such as
>>> registering an observer on an existing object. The target object would
>>> first be cloned, then the target object would be converted into a proxy
>>> that
>>> dispatches to the cloned object, but which also notifies observers about
>>> accesses/updates to the (now proxified) object.
>>>
>>  Is this the only use case?
>> If so, would it rather make sense to provide a specific Object event API
>> for existing objects? It would allow to observe accesses/updates without
>> turning the object into a proxy with arbitrary handler methods.
>>
>>
>>
>>
>>> There are a number of open issues relating to security etc:
>>> In particular, what objects can be proxified in this way - perhaps not
>>> frozen object,
>>> or objects with non-configurable properties or with unique names.
>>>
>>
>>  In today's meeting, I made two suggestions along these lines:
>>
>>  * Given the current proxy semantics, we should allow this only if the
>> object-to-be-proxified is extensible and has no non-configurable own
>> properties.
>> * We have on occasion discussed modifying the proxy proposal so that
>> individual properties could be fixed rather than just the proxy as a whole.
>> (Note: I am not in favor of such a change, but it could be done soundly.)
>> Given that this change to proxies were done, then we should allow
>> proxification only if the object-to-be-proxified is extensible, period.
>>
>>  In both cases, as you state, one effect of the operation is to remove
>> all configurable own properties from the object. In both cases, we can adopt
>> the rationale that the object-to-be-proxified could not have taken any
>> action inconsistent with it always having been a proxy.
>>
>>  In both cases, we need the further restriction that it is a kind of
>> object that can be emulated by a proxy. Today, this is technically only
>> objects of [[Class]] "Object" or "Function", but we're talking about
>> relaxing that in any case.
>>
>>
>>>
>>> A design goal is that for any object that could be proxified,
>>> we can replace it with a proxy in a way that is semantically transparent.
>>>
>>  If you provide the ability to put any functions in the handler object,
>> there in no such thing as "semantically transparent". The handler methods
>> can do whatever they wants; they are functions. Moreover with an API like
>> Proxy.createFrom(object, handler, proto), the handler methods would need
>> some help to initialize their internal proxy state in order to align with
>> the object passed as argument.
>>
>> Maybe that what you were suggesting was to use a forwarding handler by
>> default as handler and to put the handler argument as "this.target"?
>>
>> Even in this case, if creating proxies, an external user of the same
>> object has no guarantee whatsoever of seeing no semantic difference since,
>> for instance, any handler trap could throw an error when called.
>>
>> My very first (mis)understanding of proxies was that they were an object
>> access/update event API and that the handler functions were nice event
>> handler. They are not. They are much more powerful. They are not an
>> /addition/ to regular internal object methods. They are a /replacement/ of
>> it.
>>
>> However, I agree that an object event API is a valid use case (I have
>> actually had a need for that a couple of days ago), but I don't think it
>> should be a proxy extension. In my opinion, it should be its own
>> library/API. Maybe implementable/standardizable with proxies + "become"
>> internal function (see slide 56 at [1]), but its own thing.
>>
>> I would be much more in favor of something like:
>> ----
>> Object.observe(o, observers);
>> ----
>> Observers would be an object that looks like a proxy handler called on
>> every object interactions, but wouldn't be able to interact with the object
>> internal methods. It would just be an addition to internal methods rather
>> than a replacement as it's the case with proxies.
>> There wouldn't be any restriction based on property attributes
>> (enumerable, configurable, get, set...) or extensibility.
>> One question to discuss is to know if they should be called before or
>> after (or one observer method for each?) internal calls.
>>
>> Of course, if there is another use case than object access/update events,
>> maybe that turning existing objects into proxies is a good idea, but if
>> there isn't, I think that a specific API may be safer.
>>
>> David
>>
>> [1] http://www.slideshare.net/BrendanEich/metaprog-5303821?from=ss_embed
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110527/0535233d/attachment-0001.html>


More information about the es-discuss mailing list