[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Tads3] 'inherited' and propNotDefined
- From: Jesse Welton <jwelton@xxxxxxxxxxxxxxxxxxxxxxxxxx>
- Subject: Re: [Tads3] 'inherited' and propNotDefined
- Date: Fri, 12 Sep 2003 15:39:35 -0400 (EDT)
- To: tads3@xxxxxxxxxxx
BrenBarn@aol.com wrote:
>
> Jesse Welton wrote:
> -----
> Perhaps something like this:
>
> class ShadowProxy: object
> target = nil
> propNotDefined(prop, [args])
> {
> return delegated target.(prop)(args...);
> }
> ;
>
> a: object
> propNotDefined(prop, [args]) { "prop not defined: <<prop>>" }
> ;
>
> p: ShadowProxy
> target = a
> ;
>
> If we call p.xyz(), we get p.propNotDefined(&xyz), which delegates to
> a.xyz(). When we find that missing, lookup of propNotDefined must
> proceed from a, not p, for correct behavior. For consistency,
> inherited lookups should proceed the same way, from the target.
> -----
>
> I see your point, but I don't think this example really parallels the
> inheriting-undefined-properties situation, because there's no explicit
> inheritance call.
No, but there is an explicit delegation call, which is a
generalization of inheritance. It says: perform this method, using
self as the receiver, but beginning method lookup in this place.
Inheritance calls are precicely this, with "this place" being the
superclass (or superclass list).
> This has got me thinking; let me give my perspective here.
>
> My thinking is that, for the purposes of resolving this
> issue, we should consider inherited() as nothing more than a
> convenient textual substitution for an explicit call to the
> corresponding method on the base class. It relives us of the burden
> of having to manually sync the method name and class name (and it
> keeps the same self object and so forth) but essentially it is a
> call to a specific other method.
Not so. This ignores the fact that the identity of self (the
receiver) must be preserved.
A: object
x = nil;
setX(val) { x = val; }
;
B: A
setX(val)
{
"setting x to <<val>>";
inherited(val); // sets B.x, not A.x, so not equivalent to
// A.setX(val)
}
;
> To me, this clearly indicates that
> inheriting-into-a-propNotDefined lookup should NOT proceed from the
> target. The inherited call should always be a call to the method of
> the base class, and should be looked up accordingly. If no such
> method is found, propNotDefined should be called on the base class,
> because that's where we were looking for the inherited method.
You misunderstood what I meant by "target", then. In the case of
inheritance, the target is the superclass. It's not a well chosen
word, really. What would be a better term for the place from which
lookup proceeds, applicable to both inheritance and delegation?
> In addition, I think it might be fruitful to look for
> examples where we definitely would NOT want the inherited lookup to
> find a propNotDefined on the target object. (I had an example but I
> think it was pretty hairbrained so I'll keep thinking.) It seems
> that there could be situations where "inheriting" a propNotDefined
> on the target object would incorrectly delegate to the proxy object
> when what was intended was to inherit base class handling for the
> target object.
I can't think of a realistic example with 'inherited', but you could
take my example with 'delegated', remove the propNotDefined on a, and
assume the interface of a relies on the nil default for some reason.
-Jesse