> > 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.bru...@labri.fr> > >> Le 27/05/2011 04:13, Mark S. Miller a écrit : >> >> On Thu, May 26, 2011 at 5:04 PM, Cormac Flanagan <cor...@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@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss