[Proxies] VirtualHandler fundamental traps: defaults

# Tom Van Cutsem (14 years ago)

While working on the specification of the VirtualHandler < harmony:virtual_object_api> for

direct proxies, I came across the following:

As can be seen on that page, I originally considered specifying the fundamental traps of the VirtualHandler to be "abstract": the intent is for them to be overridden by client code (think Smalltalk "self subclassResponsibility"-style methods).

However, as noted on the bottom of that page < harmony:virtual_object_api#open_issues>,

an alternative would be to simply provide default implementations for fundamental traps as well. The defaults given there are, I think, the only reasonable defaults in the absence of further information.

I think this set of alternative defaults is actually more useful than requiring the fundamental traps to be abstract. For example, consider the Higher-order message proxy object (defined on the old Proxy API page: < harmony:proxies#higher-order_messages

):

With direct proxies, one could reimplement that object as follows:

var dummyTarget = {}; var _ = Proxy(dummyTarget, { get: function() {...} }); // note: handler only implements "get", default traps for all the rest

This works, as long as client code only ever uses property access on "_". Property addition, deletion etc. will all affect the dummyTarget instead, which is not really what was intended:

_.x = 1; // default behavior, equivalent to dummyTarget.x = 1 _.x // triggers get trap, doesn't return 1

Better would be to use the VirtualHandler to implement "_" as follows:

var handler = Object.create(VirtualHandler.prototype); handler.get = function() { ... }; // override only "get", inherit default traps from VirtualHandler var _ = Proxy(dummyTarget, handler);

Since VirtualHandler implements the full handler API, property addition, deletion, enumeration etc. will no longer be forwarded to the dummyTarget. If we choose reasonable defaults for fundamental traps as well, the above code is sufficient. The "_" object now behaves more reasonably in that you cannot add properties to or remove properties from it.

If, on the other hand, we choose fundamental traps to be abstract, the above code is "incomplete" and we should additionally override all fundamental traps to do something sensible (in this case, I would argue that the sensible thing to do is to implement exactly the default semantics from the "open issues" section).

So in short I would prefer sensible defaults over error-throwing missing fundamental traps. I'd be interested in hearing others' thoughts about this.

# David Bruant (14 years ago)

Le 12/12/2011 16:40, Tom Van Cutsem a écrit :

(...)

So in short I would prefer sensible defaults over error-throwing missing fundamental traps. I'd be interested in hearing others' thoughts about this.

In how they are defined and used, virtual handlers are very much like the previous proxy design (hence the easy implementation of the previous design with them). The reason why one wants to get back to the fundamental/derived distinction is because she wants to define her own fundamental traps and that derived traps use her fundamental traps. It seems natural that derived traps fail if the fundamental trap they relied on has not been defined/does not exist. That's what happened in the previous design.

I don't think that the default you propose are a good idea, because it will make bugs harder to track. Object.getOwnPropertyDescriptor returning 'undefined' for any property does not sound like a good idea. Likewise for Object.getOwnPropertyNames returning [] systematically.

Another idea would be to have no default for virtual handler fundamental trap and that the fundamental traps are the default direct proxies traps (forwarding to the target). For instance, if I want that all enumeration-related derived traps pass through my getOwnPropertyNames traps, I just define this trap in my handler which has all derived traps implemented on the VirtualHandler prototype. The object acts normally except when it comes to enumerating properties where my Object.getOwnPropertyNames is in control (as per the default virtual handler derived traps definitions).

# Tom Van Cutsem (14 years ago)

2011/12/17 David Bruant <bruant.d at gmail.com>

I don't think that the default you propose are a good idea, because it will make bugs harder to track. Object.getOwnPropertyDescriptor returning 'undefined' for any property does not sound like a good idea. Likewise for Object.getOwnPropertyNames returning [] systematically.

That is indeed a concern. Abstract methods err on the side of safety. Default behaviors can turn against you if they don't do what you expected.

Another idea would be to have no default for virtual handler fundamental trap and that the fundamental traps are the default direct proxies traps (forwarding to the target).

I don't agree here: the VirtualHandler is designed to support proxy abstractions that explicitly do not want to "use" their target object, i.e. they want to ignore the target object as much as possible. VirtualHandlers are for creating virtual objects (for instance, a remote object proxy for which there is no real physical target object acting as a backing store).

Indeed, the reason why the VirtualHandler implements the entire handler API, "overriding" all the default trap behavior, is precisely to avoid falling back to forwarding to the target.

# David Bruant (14 years ago)

[off-list]

Le 20/12/2011 14:11, Tom Van Cutsem a écrit :

VirtualHandlers are for creating virtual objects (for instance, a remote object proxy for which there is no real physical target object acting as a backing store).

Speaking of which, I'm reading the PDF version "Structure and Encapsulation in Distributed Systems: the Proxy Principle" by Marc Shapiro right now :-)