- 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