- From: Cameron McCormack <cam@mcc.id.au>
- Date: Wed, 20 Jun 2012 16:36:37 +1000
- To: Boris Zbarsky <bzbarsky@MIT.EDU>
- CC: Travis Leithead <travis.leithead@microsoft.com>, "public-script-coord@w3.org" <public-script-coord@w3.org>
I'll have a go at re-stating the questions. Assume: interface A { void f(); }; interface B { }; B implements A; interface C { }; C implements A; and also assume that you can have instances of A, B and C. The spec says that B.prototype and C.prototype have a "copy" of the property that would exist on A's interface prototype object. That wording isn't as clear as it could be, and in my mind I hadn't considered whether their values should be distinct Function objects or the same. (Is the "copy" a shallow copy of the property descriptor as a whole, so the same Function object value? Or is it a "copy" of the Function, i.e. a new one?) I think it would be fine to make the spec say that they are distinct. Now, the spec says that when a Function object corresponding to an IDL operation is invoked, that it checks the this value to ensure that it's an object that implements the interface on which the IDL operation exists. That's step 1 in http://dev.w3.org/2006/webapi/WebIDL/#es-operations. I think the spec is clear that instances of B and C are considered to implement A, so you should be able to do B.prototype.f.call(c). If, contrary to what I say earlier, B.prototype.f == C.prototype.f, then the only thing that makes sense is for that one Function object to accept a this value that is an A, B or C instance. But if we think that these Function objects should be distinct, we have the option of making each mixed-in one only accept instances of the interface it's been mixed in to. So that would mean B.prototype.f can only be called on objects that implement B and C.prototype.f can only be called on objects that implement C. This is what Boris would prefer. We also would need to consider whether A.prototype.f.call(b) and A.prototype.f.call(c) would work. My feeling is that if B.prototype.f.call(c) fails, then A.prototype.f.call(c) should also fail. So I am happy with Boris' preference, which is: * A.prototype.f != B.prototype.f && A.prototype.f != C.prototype.f && B.prototype.f != C.prototype.f * B.prototype.f.call(a) throws * B.prototype.f.call(c) throws * A.prototype.f.call(b) throws Of course if you had: interface A2 : A { }; interface B2 : B { }; then both of these calls would succeed, as usual: A.prototype.f.call(a2); B.prototype.f.call(b2);
Received on Wednesday, 20 June 2012 06:37:16 UTC