Question about direct proxies syncing their targets
Le 14/01/2012 01:57, Tab Atkins Jr. a écrit :
In the direct proxies proposal at harmony:direct_proxies, there's the following line:
get:
- Invariant checks:
- if property exists on target as a data property, updates the target’s property with the returned value
There is also the following line in introduction: "A proxy ensures that its handler and its target do not contradict each other as far as non-configurability and non-extensibility are concerned."
Consider an xrange object like from Python, which represents a numeric range (with a start, stop, and step) and exposes both an iterator and get traps.
Am I correct in assuming that, since the target of an xrange proxy is an empty object, iterating through the xrange or getting specific values from it will not fill up the target in an attempt to synchronize it with the returned values from the get trap?
My understanding is that as long as the iteration and property gets don't create or report non-writable and non-configurable properties, nothing will be done to the target.
It seems that the case you describe would be a good candidate for "virtual objects" [1]
David
On Fri, Jan 13, 2012 at 5:08 PM, David Bruant <bruant.d at gmail.com> wrote:
Le 14/01/2012 01:57, Tab Atkins Jr. a écrit :
In the direct proxies proposal at harmony:direct_proxies, there's the following line:
get: * Invariant checks: * if property exists on target as a data property, updates the target’s property with the returned value There is also the following line in introduction: "A proxy ensures that its handler and its target do not contradict each other as far as non-configurability and non-extensibility are concerned."
Consider an xrange object like from Python, which represents a numeric range (with a start, stop, and step) and exposes both an iterator and get traps.
Am I correct in assuming that, since the target of an xrange proxy is an empty object, iterating through the xrange or getting specific values from it will not fill up the target in an attempt to synchronize it with the returned values from the get trap? My understanding is that as long as the iteration and property gets don't create or report non-writable and non-configurable properties, nothing will be done to the target.
Hmm, I'm not certain whether this answers my question or not. Let me provide a more direct example. Assume the following code:
function xrange(start, stop, step) { // do error checking, default args, etc. var handler = { get: function(target, i) { var val = start + i * step; return val < stop ? val : undefined; }, iterate: function(target){...} } return new Proxy({}, handler); }
var a = new xrange(0, 100, 2); print( a[5] ); // should print "10"
In the above code, after the print statement, does the proxy's target have a '5' property set on it, or not?
It seems that the case you describe would be a good candidate for "virtual objects" [1]
Yes, virtual objects are probably a better fit for this, as I'd want only a few traps to be valid, and the rest to fail with a TypeError. However, I'm still interested in the answer for proxies.
Le 14/01/2012 03:09, Tab Atkins Jr. a écrit :
On Fri, Jan 13, 2012 at 5:08 PM, David Bruant <bruant.d at gmail.com> wrote:
Le 14/01/2012 01:57, Tab Atkins Jr. a écrit :
In the direct proxies proposal at harmony:direct_proxies, there's the following line:
get:
- Invariant checks:
- if property exists on target as a data property, updates the target’s property with the returned value There is also the following line in introduction: "A proxy ensures that its handler and its target do not contradict each other as far as non-configurability and non-extensibility are concerned."
Consider an xrange object like from Python, which represents a numeric range (with a start, stop, and step) and exposes both an iterator and get traps.
Am I correct in assuming that, since the target of an xrange proxy is an empty object, iterating through the xrange or getting specific values from it will not fill up the target in an attempt to synchronize it with the returned values from the get trap? My understanding is that as long as the iteration and property gets don't create or report non-writable and non-configurable properties, nothing will be done to the target. Hmm, I'm not certain whether this answers my question or not. Let me provide a more direct example. Assume the following code:
function xrange(start, stop, step) { // do error checking, default args, etc. var handler = { get: function(target, i) { var val = start + i * step; return val < stop ? val : undefined; }, iterate: function(target){...} } return new Proxy({}, handler); }
var a = new xrange(0, 100, 2); print( a[5] ); // should print "10"
In the above code, after the print statement, does the proxy's target have a '5' property set on it, or not?
Not it does not.
However, if you went for
Object.defineProperty(a, 5, {value: 12, configurable:false, writable:false}); a[5]; // throw a TypeError
defineProperty trap would be called. Since you did not provide one, it would by default forward to the target and would create a non-configurable, non-writable property on the target. When you try to get the property, the engine checks whether you can legitimately return 10 without breaking an invariant. Since you do break an invariant (by lying about the value of a non-writable, non-configurable property), the engine throws a TypeError.
A main difference between the old and the new proxy design, absent traps means that you want the operation to be forwarded to the target (which we can imagine can lead to some optimizations) instead of throwing.
It seems that the case you describe would be a good candidate for "virtual objects" [1]
[1] harmony:virtual_object_api Yes, virtual objects are probably a better fit for this, as I'd want only a few traps to be valid, and the rest to fail with a TypeError.
That's what virtual handlers have been introduced for.
However, I'm still interested in the answer for proxies.
Does it answer your question?
Tom Van Cutsem wrote a library [1] that runs on top of current V8 and SpiderMonkey (and so Firefox and Chrome (chrome needs to go in about:flags to activate proxies)) implementations to replace the old proxy and with the new one. I think it's faithful to he current proposal (most invariant checkink included).
Code you'd be interested to run after the insertion of the library would be
var target = {};
function xrange(start, stop, step) { // do error checking, default args, etc. var handler = { get: function(target, i) { var val = start + i * step; return val < stop ? val : undefined; }, iterate: function(target){...} } return new Proxy(target, handler); }
var a = new xrange(0, 100, 2); console.log( a[5] ); // should print "10"
console.log(5 in target); // should print false
Object.defineProperty(a, 5, {value: 12, configurable:false, writable:false});
console.log(5 in target); // should print true
David
[1] code.google.com/p/es-lab/source/browse/trunk/src/proxies/DirectProxies.js
2012/1/14 Tab Atkins Jr. <jackalmage at gmail.com>
In the direct proxies proposal at harmony:direct_proxies, there's the following line:
get:
- Invariant checks:
- if property exists on target as a data property, updates the target’s property with the returned value
This is a bug, a remnant of an earlier design in which a direct proxy would indeed keep the target "in sync" with the handler. In the current design (and draft spec, see < harmony:proxies_spec>) direct
proxies only verify the invariants, they never actively update their target anymore.
I updated the invariant checks for get and set on the wiki page.
Consider an xrange object like from Python, which represents a numeric range (with a start, stop, and step) and exposes both an iterator and get traps.
Am I correct in assuming that, since the target of an xrange proxy is an empty object, iterating through the xrange or getting specific values from it will not fill up the target in an attempt to synchronize it with the returned values from the get trap?
That's right: the proxy will not fill up the target. As David noted, this is primarily because you're exposing values for properties that don't exist on the target, so no invariants w.r.t. non-configurability have to be upheld anyway. But even in the current design, the proxy will never implicitly fill up the target. Rather, it would throw a TypeError when detecting an inconsistency.
Thanks for posting.
In the direct proxies proposal at harmony:direct_proxies,
there's the following line:
get:
Consider an xrange object like from Python, which represents a numeric range (with a start, stop, and step) and exposes both an iterator and get traps.
Am I correct in assuming that, since the target of an xrange proxy is an empty object, iterating through the xrange or getting specific values from it will not fill up the target in an attempt to synchronize it with the returned values from the get trap?