[squeak-dev] Traits use to provide class protocol in a browser?

Jakob Reschke jakres+squeak at gmail.com
Sun Oct 9 15:41:53 UTC 2022


Am So., 9. Okt. 2022 um 13:56 Uhr schrieb rabbit <rabbit at callistohouse.org>:

> On Oct 9, 2022, at 06:01, Jakob Reschke <jakres+squeak at gmail.com> wrote:
>
> 
> Hi rabbit,
>
> Traits are used by classes, not by instances, but traits can
> supply methods both to the instance side and the class side.
>
>
> Yes I understand this…still…I would generate an ETrait from the
> eventualeé’s Class. For now we’ll assume a spherical cow and so the
> eventualeé’s class is local. This is our useCase, an ETrait…
>
> If that class were unknown to the client, an eventual ‘eref class
> asETrait’ would return the ETrait for that class over the inet to the
> client, in an archived box, pass-by-copy, a later detail. Spherical cow.
>
>
Is there a particular reason to send/make a trait rather than a class? In
particular if you need dynamically generated subclasses of ERef anyway.


> If you use a trait in a class, the trait's methods are copied to the
> MethodDictionary of that class (and the corresponding classTrait methods go
> to the dictionary of the corresponding Metaclass).
>
>
> Right so what are the method implementations of an ETrait? This is the key
> to my using them. As this is strictly for documentation and browsing of the
> class of an instance, for those developers who ask “what are the messages I
> can send to my ERef?” Open a browser on its class and see!
>

Not sure whether putting something that the system can potentially
execute into the system is the right way to obtain something "strictly for
documentation"... A common pattern that I observe is that people mold all
kinds of things into Smalltalk code just because the tools for browsing it
are already there. Rather than build proper tools for the things that are
actually not Smalltalk code...


These methods need be eventually send to the eventualeé. Andsoi think the
> method implementations in the ERef’s subclassed ETrait (see below, ERef
> subclassing for each ETrait) provides the entire non-private (private
> category, methods starting with prv, priv, prim would be excluded from the
> ETrait’s methods.
>
> If you then change the method on the trait, it will automatically update
> those method copies in the using classes.
>
>
> Interesting this! So an ETrait generated from a Class ought have the same
> update with the ETrait’s customized method implementations…
>
> add/remove a method on the ETrait’s defining class (class asETrait) ought
> to update the ETrait with the eventualized method implementation, which
> will update the ERef’s class through normal Trait mechanism. Ask a class
> #eRefClass to get the ERef subclass for that class’ ETrait. Keep
>

Let's assume the actual spherical cow runs in the remote system. Locally
you have an ERef to the spherical cow, and let's assume that this ERef is
actually a member of a subclass of ERef that uses some trait that describes
the spherical cow. When the spherical cow is updated in the remote system,
you would have to take care of sending that update to the local system
yourself. Your implementation could then locally update the trait
describing the spherical cow, to update the methods in that ERef subclass.
Again I wonder why there needs to be a trait here. You could also update
that subclass directly.

Even if this all runs in the same image, and the spherical cow just runs in
a different Vat than the one where the ERef to it is, you would still need
to implement it yourself that the generated trait or subclass gets updated
if you update the real spherical cow class.


>
> These ETraits would need to be instance specific, not class-based, UNLESS
> a new ERef subclass is auto-generated as needed for different eventualeé’s
> ETrait generating Class.
>

As I said, traits are attached to classes, so you would definitely need all
these auto-generated subclasses. And then, once more, why generate both a
trait and a subclass, when just the subclass would be enough.


>
> With different ERef subclasses for each target class, with that particular
> ETrait, browsing the ERef subclass in any browser should be fine displaying
> the ETrait methods..
>
>
Yes.


>
> When you implement your own method in the class, even though that method
> would also be provided by a trait that the class uses, the trait will skip
> that method and leave your own method in place.
>
>
> Not necessary, I think. Possible to specify read-only method
> implementations?
>

What do you mean "Not necessary"? This is how it works. If you don't want
that, you will need to find a workaround or use different means. I do not
understand what you mean by "read-only method implementation", but there is
no possibility that I know of to avoid that trait methods "back out" if the
class already has a method that the trait also provides.


> If you want a dynamic, instance-specific display in the protocol browser
> (or rather InstanceBrowser), at the first glance it does not sound to me
> like traits would be a fit.
>
>
> Instance browser? Huh! Unknown to me…
>

When you use "browse protocol" on classes (e. g. from the system browser),
you will get a Lexicon (which is-a ProtocolBrowser). When you use "browse
protocol" on objects (e. g. from an Inspector), you will get an
InstanceBrowser, which looks exactly like a Lexicon except that the frame
color is slightly different (if you have colorful windows enabled). The
main useful difference is that if you evaluate code in the text pane of an
InstanceBrowser, it will evaluate in the context of that inspected object,
as if you would evaluate the code in the inspector for that object.

If you wanted to tweak a tool to display some instance-specific behavior
(without generating subclasses), you would adapt/extend/subclass the
InstanceBrowser I think.


> If you can derive the methods just from the reference to the remote class,
> you should better override those messages that the browser sends to
> determine which methods there are in your eref class. Or implement a custom
> browser that sends different messages to collect that information.
>
>
> The generation of an ETrait from a eventualeé’s Class will compile methods
> for explicit eventual sending (no #doesNotUnderstand, though that will
> remain) with non-private selectors as
>
> derivedMessageSelector: arg1
>     ^ self redirectMessage: (EMessageSend
>         selector: derivedMessageSelector
>         arg: arg1)
>
> Which when called will return an EPromise.
>
> In this way ERef subclasses per ETrait can provide the interface with
> forwarding implementations of the Class’ protocol.
>
>
The net effect is that when the ERef receives this message, it will go
through this generated method rather than through doesNotUnderstand:, plus
you have put up this stub method so that the unchanged Smalltalk tools have
something to display. If you think that is worth it, alright. But again,
you would get the same effect with just generated subclasses, without using
any traits.

Kind regards,
Jakob
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20221009/371e5b29/attachment.html>


More information about the Squeak-dev mailing list