Non-generic traps for non-generic objects (was: Overriding Map/etc with get/set hooks?)

Tab Atkins Jr. jackalmage at gmail.com
Thu May 23 16:51:25 PDT 2013


On Tue, May 21, 2013 at 4:07 AM, David Bruant <bruant.d at gmail.com> wrote:
> David Bruant wrote:
>> Le 21/05/2013 04:06, Tab Atkins Jr. a écrit :
>> > (One way to do this today is to subclass Map and provide my own
>> > get/set/etc. functions, but I need to override a potentially-open set
>> > (anything that doesn't directly lean on my overridden functions), and
>> > it doesn't prevent people from directly twiddling my [[MapData]] by
>> > calling Map.prototype.set.call() on my object.)
>>
>> If you want to keep control over how people interact with your key/value
>> interface, a proxy seems more appropriate. It's been designed so that
>> you have full control and can't be bypassed.
>>
>> Although the behavior Map.prototype.set.call(someProxy) isn't very clear
>> yet spec-wise [1] you can be sure that it won't be possible to freely
>> mess around an internal [[MapData]] (because it would open an undesired
>> communication channel)
>
> Would it make sense to add specific traps for specific objects (Date would
> have some specific traps, so would objects with [[MapData]], so would
> objects with [[SetData]], etc.)?
> Very much like functions currently have some traps that only apply to them.

With more thought, it seems like this, or something roughly equivalent
to it, is indeed the correct solution.

It's impossible for me to reliably proxy Maps today.  If I subclass
Map and provide my own implementations of set() and delete(), authors
can (accidentally?) work around them by calling
`Map.prototype.set.call(style.vars, obj1, obj2)` and corrupt my map.
Even if the C++ side stringifies things (which, spec-wise, still
requires the kind of hooking that's been frowned upon in these
threads), I've got a confusing Map where two different keys both map
to the same CSS property, and I have to define that behavior somehow,
which is dumb.

(And of course, if I *dont'* subclass Map, then I'm in the unenviable
position of reimplementing the entire Map API myself, including things
that have nothing to do with my extra constraints like Map#keys(), and
then having a static snapshot of the Map API stuck in my spec, which
won't be automatically upgraded when the Map API grows.  I don't
consider this an acceptable outcome.)

So, yeah, I need a way to hook the specific internal Map operations
somehow.  I could do it with nothing more than Map-equivalents to the
four special operations that WebIDL allows me to define.

I don't care if this is exposed as additions to the set of Proxy
traps, or via special Symbols on the Map that are used for those
operations, or something else.

~TJ


More information about the es-discuss mailing list