[squeak-dev] [Bug & design issue] Messages understood or not understood by ProtoObject

Thiede, Christoph Christoph.Thiede at student.hpi.uni-potsdam.de
Fri Feb 14 13:34:06 UTC 2020


(Separate idea, separate post:)


The main (may I say the only?) use case of ProtoObject is to have a minimum superclass for generic proxies or decorators that are implemented generically using #doesNotUnderstand:.

Besides this mechanism, we also have #run:with:in: (see ObjectsAsMethodsExample).

Would it, hypothetically spoken, be worth a thought to implement some kind of hook on VM side/code simulation that is called before sending any message to a new receiver? Very pseudo:


MyCoolProxy >> #unmanagedPerformMessage: aMessage

    "by implementing this method on a class, you tell the engine to call it before sending any message from a different object to the receiver

    (we could also use something like #flush for this)"

    aMessage = #inspectorClass ifTrue: [

        ^ aMessage sentTo: self "don't forward this message"].

    self log: aMessage. "sending a message to the receiver does not invoke #unmanagedPerformMessage:"

    "Finally ..."

    ^ aMessage sentTo: myTarget

Probably there is at least one very good reason not to implement this, besides confusion and (maybe?) performance. But I would be delighted to hear this reason :-)

Best,
Christoph


________________________________
Von: Squeak-dev <squeak-dev-bounces at lists.squeakfoundation.org> im Auftrag von Thiede, Christoph
Gesendet: Freitag, 14. Februar 2020 14:18 Uhr
An: Squeak Dev
Betreff: [squeak-dev] [Bug & design issue] Messages understood or not understood by ProtoObject


Hi all! :-)

When we were fiddling around with some proxy implementations today, Marcel and I discovered an interesting set of issues regarding ProtoObjects.

Let's start with a concrete bug:


Code to reproduce <do it>:

ProtoObject new class.


Expected behavior:

DNU exception, because #class is implemented on Object only.


Actual behavior:

Outputs ProtoObject.

Even stranger: If you debug the method instead and simulate the #class send, you get a "simulated message class not understood" error.

If you subclass ProtoObject and override/forward #class, the results will deviate based on whether you are debugging or executing the code.


Some thoughts:

There are two options: Either to implement #class on ProtoObject (by moving the primitive definition up from Object), or to remove it from the specialObjectsArray so that a send to #class is not compiled differently than a send to any other regular message.


This leads us to the rather general question: What special messages should an instance of ProtoObject understand?

We don't answer this question completely consistent at the moment: For example, #instVarAt: is implemented on Object, but #instVarsInclude: is implemented on ProtoObject. Again, it is a bit weird that the implementation of #instVarsInclude: calls #class which is implemented on Object only. And so it goes on:

  *   #someObject is implemented on Object, but #nextObject is available in ProtoObject.
  *   #withArgs:executeMethod: is implemented on ProtoObject, whereas #perform:withArguments: is on Object.
  *   #ifNotNil: is implemented on ProtoObject; however, #ifNotNilDo: is implemented on Object. (btw: does the latter still have any raison d'ĂȘtre?)
  *   #flag: exists on ProtoObject, and #yourself exists on Object only. Isn't #yourself rather a syntactical element we would like to behave exactly the same way for every possible message receiver? (btw: Is there a good reason not to speed up #yourself via specialObjectsArray)?
  *   (I don't claim for completeness)

And just some other problems regarding to ProtoObject (just collecting them here instead of forgetting them forever):

  *   ObjectTracer is broken due to several reasons. Will fix this soon.
  *   Inspectors cannot inspect ProtoObjects correctly (for example: Inspector openOn: (ObjectTracer on: Display)). This is because #instVarAt: is implemented on Object only so this message is forwarded.
Maybe we should replace these critical calls from Inspector by something like #tryPrimitive:173withArgs:? But should we do so in Inspector or rather in a new subclass named ProtoInspector or similar? Hm, then we would need to implement #inspectorClass on ProtoObject, which is bad either ... We will keep investigating this issue.

However, the crucial question is: What special messages should an instance of ProtoObject understand? On the one hand, the idea of ProtoObjects is to work as total proxies with a maximum amount of forwarding potential, which implies a minimum number of methods. On the other hand, certain aspects such as accessing instvars or executing messages are really identity-related. Looking forward to your comments :-)

Best,
Christoph
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20200214/9c7f48f9/attachment.html>


More information about the Squeak-dev mailing list