Thanks martin
At GemStone we work a lot with our own proxies which represent objects in another VM. We also have our own inspectors and debuggers to inspect these effectively. Over the years I've made a lot of design mistakes in this area and have had to fix them. Along the way I have come to some definite opinions about how inspectors and proxies should interact:
* When inspecting a proxy, the proxy should look to the user like a proxy, not like the object being proxied. To do otherwise causes great confusion for the person using the inspector. Ideally, an inspector offer the option to have multiple views of the same object, a basic view which shows the low-level structure and possibly higher-level views which show the logical structure of objects which the inspector knows how to do special things for. So for instance sets show their real instvars (tally, array) for the basic view but their elements and size for a logical view. For proxies the higher-level view might be to inspect the object being proxied.
* Inspectors should never assume that the object being inspected can respond to *any* message. In the case of Pharo it's probably OK to assume that all objects inherit from ProtoObject, but IMO if debugging tools are designed correctly ProtoObject should not be needed and proxy classes can inherit directly from nil and implement no methods other than #doesNotUnderstand:. To achieve this an inspector should send no messages to an object until it knows something about how that object will respond to the message. It is *not* safe to send a not-understood message and catch the exception, because a proxy's response to a not-understood message may change the state of the proxy or other objects in the local or remote system, and debugging tools should only change the state of the system when explicitly told to. To achieve this you need a primitive to determine the "real" class of an object without sending that object a message. I don't know if Pharo currently has this, but it's very useful, and extremely simple to implement. VW has a minimal reflection API that includes this, and GemStone recently added a fairly complete reflection API that allows determining class and size of an object as well as getting setting values of its instvars all without sending the object any messages.
do you mean mirror like code that eliot was mentioning recently?
This reflection facility is not really object-oriented, since it examines and changes state of objects without sending the object messages, breaking encapsulation. However, this is useful, and I don't think it's any worse than the existing messages like #instVarAt:(put:) which fulfill the same function. These existing messages also break encapsulation and are at such a different level of abstraction from the rest of the object's protocol that they aren't really good object design either.
* Once the inspector knows what the class of the inspected object is, it can send messages to the class (which even for proxy classes inherits from Behavior) to determine what inspecting facilities to offer. Object class would answer only the basic inspector, Set class would override this to add Set-specific inspector(s), Dictionary class would override again to replace the Set-specific inspectors with Dictionary ones, and so on.
Some of this modularity is already in the new inspector, but the important notion that is missing is "Send *no* messages to an object until you know what kind of object you're dealing with".
Regards,
-Martin
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project