Damn...

Ancestors, multiple inheritance, aggregates, managers, subjects, elements...
Arrggh... ne ne need to get back to reading, that book that every OOP 
designer should know.

>  > This is how I usually implement overriding while still using the 
>superMethod:
>  >
>  > on mMethod me
>  >    --<specific subClass implementation>--
>  >    return callAncestor(#mMethod, me)
>  > end
>
>I've been doing something much the same:
>
>return call (#mMethod, ancestor)

Ahh, subtle but important distinctions here.
<return call (#mMethod, ancestor)>
achieves the same as:
<ancestor.mMethod()>

Which causes the 'me' parameter in the called method, to point to the 
ancestor itself, and not to the significant subClass. The object 
begins to suffer from "split personality disorder" This has some 
consequences:

If 'mMethod' calls other methods in the 'object', then the calls will 
not be routed through any overriding implementations in the subClass. 
The specific implementation of the subClass is ignored, which sort of 
breaks the foundation of inheritance.  ;-)

Also, if mMethod calls other objects, and sends it's address as an 
argument, for the other objects to store for later callback, then 
these other objects, will store the address of the ancestor, and not 
the true address of the 'object'. Again causing the implementation of 
the subClass to be ignored.

Using:
<return callAncestor(#mMethod, me)>
causes the 'me' parameter in the called method, to point to the 
subObject, rather than the ancestor. Just as it would (and should), 
if the message had passed through a subObject, without an 
implementation of the method.

I think, this pretty well explains, why Lingo has such a keyword as 
'callAncestor'.

And while we are at 'call':

I saw it somewhere else recently, but I can't see any specific reason 
for the use of the syntax,
  <call (#mMethod, object)>
In situations where the the method to call is fixed. As I said,
<object.mMethod()>
would achieve the same. (please correct me if I'm wrong)

I can think of these reasons for using call:
1: the method to call is dynamic, ie: residing in a variable.
2: you have a list of objects to call.
3: You want to be able to call one or more objects in list, with a 
method, which they may have implemented.
Of course the list could probably be extended.

So sometimes, especially when using generalized agents, that makes 
callbacks to their client, I use a syntax like:
<call (#mMethod, [object])>
Embracing the object allows attempts to call unimplemented methods, 
without an error.
Here: Allowing the agent to attempt the callback regardless of the 
capabilities of the client.

Disclaimer: Any insults inflicted by this mail are purely 
coincidental, and not caused by intentional bad will, on the authors 
part. (how could any kind of 'will' be unintentional?  ;-)


===============================
Cheers, Jakob Hede Madsen.
email:    <mailto:[EMAIL PROTECTED]>
===============================


[To remove yourself from this list, or to change to digest mode, go to
http://www.penworks.com/LUJ/lingo-l.cgi  To post messages to the list,
email [EMAIL PROTECTED]  (Problems, email [EMAIL PROTECTED])
Lingo-L is for learning and helping with programming Lingo.  Thanks!]

Reply via email to