[self-interest] Re: The problem of dynamic inheritance
Jecel Assumpcao Jr
jecel at merlintec.com
Tue Jan 13 20:44:20 UTC 2004
On Tuesday 13 January 2004 16:17, cyberbaixing wrote:
> > > a _Define: (|
> > > f = ('a' printLine. p:b. f).
> > >
> > > |)
> > Note that this object doesn't understand either the 'p:' nor
> > the 'b' messages. And the final 'f' will cause infinite recursion.
> I want to know why the object a doesn't understand 'p:' and the 'b'
The object has a single slot named 'f'. It will not directly understand
any other message than that. Since it doesn't have any parents, any
other message than 'f' will cause a run time error.
> Doesn't this clause pass the syntax check?
The syntax is perfectly valid. Sending a message that an object doesn't
understand is an error at run time, not something that is checked when
the parser converts your text into bytecodes.
> Why the final 'f' will cause endless recursion?
It depends on what effect "p: b." has. In your example you are trying to
modify the meaning of sending 'f' to the object (which doesn't work for
"a f", but does work for "c f" as I explained in the previous email),
but if that didn't happen then the final 'f' would call the exact same
method in which it appears, which will call the same method again which
will call the same method again and so on.
> Are there other cases
> also cause infinite recursion? How can I avoid them?
Don't invoke a method within itself unless you have a condition for
stopping. This will cause infinite recursion
spiral: n = (forward: n.
while this won't
spiral: n = (forward: n.
n<600 ifTrue: [spiral: n+4])
> How can I accomplish the same result of resends by dynamic
Resends are for accesing methods that would be hidden by those defined
in the local object. For example, if the local object has 'f' and the
parent object also has 'f' then you have to use a resend if you need to
use the parent's version for some reason.
Dynamic inheritance is for changing the behavior during the execution of
I don't see any relation and so don't know how to answer your question.
> c _Define: (|
> p*<- a.
> b = b.
> f = ('c' printLine. resend.f).
> In definition of c, I can understand the clause 'p*<- a.'. It means a
> is the parent object of c. But the clause'b =b.', Does it also mean b
> is a parent of c?
'p' is a parent because you defined the slot as 'p*'. Any slot with an
"*" at the end of its name points to a parent. That is not the case for
'b' and 'f', so they are just "regular" slots.
> Else, I don't understand why the output of c f is
> Why c appears two times? I guess it is related with the function
> printLine since if I delete it, the output has no any "c".
First we call the method (to use a Smalltalk notation) c>>f, which
prints the first 'c'. Next we execute "resend.f" which calls the method
a>>f (since the parent of c is a) which prints the 'a'. Then (still
inside a>>f) we execute "p: b" which changes the contents of the 'p'
slot in c (!!!! not a !!!!). The final step of a>>f is to send 'f' to
self, which is 'c' in this context so we execute c>>f next. That prints
another 'c' and then calls b>>f (since the parent of c is now b). That
prints a 'b' and then returns the string 'b' as the final result of all
this mess (all methods return values in Self. Always!).
> Why object a works this time without the result of a f which is:
> No 'b' slot found in a slots object.
Object c defines a 'b' slot, but object a does not. So a method which
sends 'b' to self will work for one object but not the other.
> Why b appears two times but with different forms?
The first b (without the ' around it) is what is printed by the
printLine method, while the second 'b' is what the read/eval/print loop
prints as the final result of your code.
More information about the Self-interest