Aren’t membranes incompatible with private data via WeakMaps?
Answering the question in the subject line, no. The key is the difference between a standalone proxy and a membrane. With a membrane, the key is that the:
- Countdown class
- Countdown.prototype
- Countdown.prototype.dec
- instances of the Countdown class
- the WeakMaps used by the Countdown class to store it private state (_counter, _action)
are all on one side of the membrane. As is conventional, let's call that the wet side, and the other side the dry side. Say both a Countdown instance c and the WeakMap _action get passed through the membrane. Let's name the corresponding dry proxies dry_c and dry_action. If, on the dry side, someone does
dry_action.get(dry_c)
then this would trap on dry_action, passing dry_c back through the membrane, resulting in the dry_action handler performing, on the wet side
const r = _action.get(c)
The wet result, r, of this invocation would get passed back through the membrane, leading to the original expression returning dry_r.
Alternatively, let's say that someone on the dry side does
dry_c.dec()
This traps on dry_c, which looks up c's inherited "dec" method, passes that back through the membrane, resulting in a dry_dec proxy for that method. When that is invoked with dry_c as its this, it traps, invoking the wet dec method with c as its this.
Conclusion: it all works fine.
Thanks! I forgot about unwrapping.
Take, for example, the following class, which uses WeakMaps for its private data:
let _counter = new WeakMap(); let _action = new WeakMap(); class Countdown { constructor(counter, action) { _counter.set(this, counter); _action.set(this, action); } dec() { let counter = _counter.get(this); if (counter < 1) return; counter--; _counter.set(this, counter); if (counter === 0) { _action.get(this)(); } } }If you wrap an instance of
Countdownwith a revocable Proxy (e.g. when it is returned by a method inside a membrane) that resets its private state, because itsthischanges.Right? If yes then I’d expect that to cause problems for code that uses WeakMaps for private data.
Take, for example, the following class, which uses WeakMaps for its private data: ```js let _counter = new WeakMap(); let _action = new WeakMap(); class Countdown { constructor(counter, action) { _counter.set(this, counter); _action.set(this, action); } dec() { let counter = _counter.get(this); if (counter < 1) return; counter--; _counter.set(this, counter); if (counter === 0) { _action.get(this)(); } } } ``` If you wrap an instance of `Countdown` with a revocable Proxy (e.g. when it is returned by a method inside a membrane) that resets its private state, because its `this` changes. Right? If yes then I’d expect that to cause problems for code that uses WeakMaps for private data. -- Dr. Axel Rauschmayer axel at rauschma.de rauschma.de