[self-interest] Re: Objects with dynamic slots

Jecel Assumpcao Jr jecel at lsi.usp.br
Mon Aug 30 22:03:53 UTC 1999


> cluster = (|
>   parent = defaultBehavior.        "note, no parent slot!"
>   values.                          "where to store the values"
>   clone = (_clone values: dictionary clone).   "
>   doesNotUnderstand: aMessage = (
>     values at: aMessage selector IfAbsent: [
>       "etc".
>       "otherwise..."
>       aMessage delegateTo: parent] "forward message to parent"
>   )
> |)
> 
> This allows us to intercept even inherited messages - something which isn't
> possible in Smalltalk.  The only problem is to hide "parent" and "value",
> perhaps by renanming them to "hidden_parent" or "my_values".
> 
> Thank you for listening, I think I found the answer :-)

I got the following to work as you wanted. It took me a long time
to find out how the process object handles undefined messages -
it is not very efficient at all :-(

cluster = (|

   hidden_parent = defaultBehavior. "as you suggested"

   my_values <- dictionary copyRemoveAll. "it is a bad idea to start
                                           with nil. And here we
                                           can access 'dictionary' for
                                           sure, while inside 'clone'
                                           it might not work"

   clone = (_Clone my_values: my_values copyRemoveAll).

   undefinedSelector: sel
                Type: msgType
           Delegatee: del
        MethodHolder: mh
           Arguments: args = (my_values at: sel IfAbsent: [
                                  'x' = sel ifTrue: [^1].
                                  sel sendTo: self
                                      DelegatingTo: hidden_parent.
                              ]).

|)

I can send 'clone', 'x', 'identityHash' (found in defaultBehavior)
and all seems to work. By doing

       my_values at: 'f' Put: 9

we can now send 'f' to this object and get the correct answer.
Of course, you can see that a *lot* more testing should have been
done in the 'undefined...' method (just look at all those arguments
we didn't use). Sending 'g' will generate a stack overflow, for
example (since delegating to hidden_parent fails, resulting in
infinite recursion. And as we all know, the only thing worse than
infinite recursion is infinite recursion ;-)

Anyway, while it is nice that this works at all, if you have a
reflective implementation (hence the "R" in my upcoming Self/R)
where you can get direct access to the message passing mechanism
itself, then you can do these kind of things in a much more
natural way. You might want to take a look at the Moostrap
language (see its entry in the following chart of prototype languages:
http://www.slip.net/~dekorte/Proto/Chart.html).

-- Jecel



More information about the Self-interest mailing list