there is a really nice discussion on supporting (not having an inspector breaking) when browsing
proxy. Can you have a look? http://code.google.com/p/pharo/issues/detail?id=1970 "What happens is the inspector asks for "self class allInstVarNames" and then tries to get each value with "self instVarNamed: aName". The problem is, self class allInstVarNames answers the instVars of the future class, but "self instVarNamed: aName" gets passed up to the MIMEDocument by #doesNotUnderstand: and the MIMEDocument throws an error because of course it doesn't have the correct instant vars. The old inspectors weren't as intrusive and worked, these new tools clearly still have some bugs. Since ProtoObject, the superclass for any such proxies doesn't do #instVarNamed:, such code in the inspector will blow up anytime one attempts to inspect any kind of proxy. I would report this as a bug to whoever is maintaining the new inspector tools." So the only way I know to produce the 'bug' is to load the SFuture class he describes in the blogpost I mention above then run the example I posted in step two. If this is the wrong place to report this then let me know and I'll keep looking for the correct place. Delete commentComment 4 by pdebruic, Today (14 hours ago) The default, I think. I haven't changed anything. SystemBrowser default Ctrl-p gives OBSystemBrowserAdaptor Delete commentComment 5 by marcus.denker, Today (11 hours ago) I think the problem is this: -> ProtoObject implements a *minimal* object. This way, Proxies or Futures can use #doesNotUnderstand to implement what they implement. That is, for the example of the Proxy, every message is forwarded to the remote object. -> Now we do not know what exactly you want to forward. Should an inspector inspect the local proxy? Ot the remote object? You decide. Your subclass of ProtoObject copies as many objects from Object as you want. (often all that are needed to inspect the *proxy* vs. the remote object). I think Ramon fine-tuned his implementation for the normal old inspector. Now when you use another one, it uses other methods in addition to the one implemented in the Future --> confusion. Chaos. Bug. But: We can not fix this. this is purely the responsibility of the implementor of the subclass of ProtoObject. So. next action: -> We fix (uhm, remove) the croquet Future code that is just plain confusing. -> We think hard if it's really a problem in the new inspector vs. a missing method on the Future. (and, yes, all this sucks anyway.... we are hard at work to make reflection better and solve all this in a *much* nicer way... but that's research...) Delete commentComment 6 by ramon.leon, Today (10 hours ago) It's not just the Future proxy that'll have problems, it's proxies in general. The way the current inspector is written won't work with any proxy I see in my image, SoapHref, SFuture, MAProxyObject, MADynamicObject, probably the Glorp record proxy, because it assume it can use #instVarNamed: on an instance using values from "anInstance class allInstVarNames" which in the case of *any* proxy won't work unless the proxy implements a version of #instVarNamed:. This is confusing because now the proxy is no longer behaving as a proxy, now reflectively it's answering values for itself rather than the instance being proxied. Another solution would be if the proxy overrode #class to return the class of the proxied instance, but I've always assumed all hell would break loose if you overrode #class, I didn't think it safe to do, and I've not seen any other proxy class do this. Regardless of the ultimate solution, the inspector shouldn't blow up, it should catch the exception and have some default rendering behavior for when it can't inspect an object for some reason. Do you not agree? Delete commentComment 7 by stephane.ducasse, Today (moments ago) Yes I agree. We should contact frederick. I think that the inspector should know that it is browsing a proxy and pay attention. _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
Hello
I was implement proxy for Mocketry project. My proxy (MockObject) can emulate messages sush #printOn: and others that used by tools (debbugger, workspace and others). MockObject just search some tools context in #doesNotUndarstand method context. And if message was sent by tools (not domain code) proxy evaluate it in appropriate way. For example, when #printOn: was sent by debbuger, proxy prints special name instead of record/replay this message. But search full context chain for each message is really cost operation. But for mock-framework it's not problem I thing. Maybe tools must mark process in which it work. And proxy would easilly know that message sent by tools. 2010/2/16 Stéphane Ducasse <[hidden email]> there is a really nice discussion on supporting (not having an inspector breaking) when browsing _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
On Feb 16, 2010, at 10:36 AM, Denis Kudriashov wrote: > Hello > > I was implement proxy for Mocketry project. My proxy (MockObject) can emulate messages sush #printOn: and others that used by tools (debbugger, workspace and others). MockObject just search some tools context in #doesNotUndarstand method context. And if message was sent by tools (not domain code) proxy evaluate it in appropriate way. For example, when #printOn: was sent by debbuger, proxy prints special name instead of record/replay this message. Cool Could you publish your code that we learn? For debugging speed should not be an issue. I remember that igor mentioned something related to printOn: / displayString a while ago. Stef > But search full context chain for each message is really cost operation. But for mock-framework it's not problem I thing. > > Maybe tools must mark process in which it work. And proxy would easilly know that message sent by tools. > > > 2010/2/16 Stéphane Ducasse <[hidden email]> > there is a really nice discussion on supporting (not having an inspector breaking) when browsing > proxy. Can you have a look? > > http://code.google.com/p/pharo/issues/detail?id=1970 > > > "What happens is the inspector asks for "self class allInstVarNames" > and then tries to get each value with "self instVarNamed: aName". The > problem is, self class allInstVarNames answers the instVars of the > future class, but "self instVarNamed: aName" gets passed up to the > MIMEDocument by #doesNotUnderstand: and the MIMEDocument throws an > error because of course it doesn't have the correct instant vars. > > The old inspectors weren't as intrusive and worked, these new tools > clearly still have some bugs. Since ProtoObject, the superclass for > any such proxies doesn't do #instVarNamed:, such code in the inspector > will blow up anytime one attempts to inspect any kind of proxy. I > would report this as a bug to whoever is maintaining the new inspector > tools." > > So the only way I know to produce the 'bug' is to load the SFuture class he describes > in the blogpost I mention above then run the example I posted in step two. If this > is the wrong place to report this then let me know and I'll keep looking for the > correct place. > > > Delete commentComment 4 by pdebruic, Today (14 hours ago) > The default, I think. I haven't changed anything. > > SystemBrowser default Ctrl-p gives OBSystemBrowserAdaptor > > Delete commentComment 5 by marcus.denker, Today (11 hours ago) > I think the problem is this: > > -> ProtoObject implements a *minimal* object. This way, Proxies or Futures can use #doesNotUnderstand > to implement what they implement. That is, for the example of the Proxy, every message is forwarded to the > remote object. > -> Now we do not know what exactly you want to forward. Should an inspector inspect the local proxy? Ot the > remote object? You decide. Your subclass of ProtoObject copies as many objects from Object as you want. > (often all that are needed to inspect the *proxy* vs. the remote object). > > I think Ramon fine-tuned his implementation for the normal old inspector. Now when you use another one, > it uses other methods in addition to the one implemented in the Future --> confusion. Chaos. Bug. > > But: We can not fix this. this is purely the responsibility of the implementor of the subclass of ProtoObject. > > So. next action: > -> We fix (uhm, remove) the croquet Future code that is just plain confusing. > -> We think hard if it's really a problem in the new inspector vs. a missing method on the Future. > > (and, yes, all this sucks anyway.... we are hard at work to make reflection better and solve all this in a *much* > nicer way... but that's research...) > > > Delete commentComment 6 by ramon.leon, Today (10 hours ago) > > It's not just the Future proxy that'll have problems, it's proxies in general. The > way the current inspector is written won't work with any proxy I see in my image, > SoapHref, SFuture, MAProxyObject, MADynamicObject, probably the Glorp record proxy, > because it assume it can use #instVarNamed: on an instance using values from > "anInstance class allInstVarNames" which in the case of *any* proxy won't work unless > the proxy implements a version of #instVarNamed:. > > This is confusing because now the proxy is no longer behaving as a proxy, now > reflectively it's answering values for itself rather than the instance being proxied. > > Another solution would be if the proxy overrode #class to return the class of the > proxied instance, but I've always assumed all hell would break loose if you overrode > #class, I didn't think it safe to do, and I've not seen any other proxy class do this. > > Regardless of the ultimate solution, the inspector shouldn't blow up, it should catch > the exception and have some default rendering behavior for when it can't inspect an > object for some reason. Do you not agree? > > Delete commentComment 7 by stephane.ducasse, Today (moments ago) > Yes I agree. > We should contact frederick. > I think that the inspector should know that it is browsing a proxy and pay attention. > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
http://www.squeaksource.com/Mocketry.html
Maybe in pharo it's not work. But should be loadable See class MocketryProxy - #doesNotUnderstand. For debugging speed should not be an issue. For debugging yes. But that approach is issue for use such proxies in domain tasks. Any message to proxy iterates full context chain when message sent by domain _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
On Feb 16, 2010, at 11:47 AM, Denis Kudriashov wrote: > http://www.squeaksource.com/Mocketry.html > Maybe in pharo it's not work. But should be loadable > > See class MocketryProxy - #doesNotUnderstand. > > For debugging speed should not be an issue. > > For debugging yes. But that approach is issue for use such proxies in domain tasks. Any message to proxy iterates full context chain when message sent by domain ok I see. Thanks denis. We should find a simple solution for the bug. Stef > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
In reply to this post by Stéphane Ducasse
Stéphane Ducasse wrote:
> there is a really nice discussion on supporting (not having an inspector breaking) when browsing > proxy. Can you have a look? > > http://code.google.com/p/pharo/issues/detail?id=1970 > Thanks for the summary. 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. 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 [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
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 > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
Stéphane Ducasse wrote:
>> 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? The discussion on mirror primitives on the Squeak-dev list on September 7 and December 16? Yes, exactly. -Martin _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
In reply to this post by Martin McClure-2
My 2 cents.
On 16 February 2010 19:49, Martin McClure <[hidden email]> wrote: > Stéphane Ducasse wrote: >> there is a really nice discussion on supporting (not having an inspector breaking) when browsing >> proxy. Can you have a look? >> >> http://code.google.com/p/pharo/issues/detail?id=1970 >> > > Thanks for the summary. > > 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. > +1. Inspectors should display proxies, not proxied objects. > * 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. 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". > -1 here. I don't like breaking encapsulation. You gain nothing from revoking control from the object how to expose its own contents. Let me illustrate why: Suppose you want to print ivars of a proxy object without sending any messages to it. Okay, by using a primitive (which breaks encapsulation) you getting an object's class. And now you can send messages to that class.. Which is fine, except on some extreme cases one could have own class hierarchy, which not inherits from Behavior. So, you introducing a limiting factor along the way... Now, suppose that by doing such trickery you extracted some object from one of inspected object ivars. But hey, extracted object can be in own turn a proxy, and printing it may cause a side effects! Now, how you suppose to print anything without sending any message? A deadlock. So, since you can't avoid sending a message, then why doing this black voodo at all? Why not just establish a system-wide minimal protocol and say that all objects in system should respond with #mirror message, or #readOnlyMirror, if you like? Then, a) you don't have to break encapsulation b) any object could decide by itself, in what fashion to expose own contents. Problem solved. > Regards, > > -Martin > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project -- Best regards, Igor Stasenko AKA sig. _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
Free forum by Nabble | Edit this page |