Hello guys,
i'd like to discuss with you an idea of having a specific methods in Object class for a better and more clever behavior when debugging. For those of you who are using different kinds of proxies, the main problem with them that you should override the #printOn: or #printString methods in order to behave them similar to what original(proxied) object should be, but from other side, especially for debugging purposes, this incurs a major inconvenience, because you often need to differentiate between the real object and object proxy while debugging. Because if proxy behaves similar to proxied object while printing, you can't really make a difference when looking at it. So, i thought that a nice solution would be to extend an Object protocol especially for debugging purposes by adding #debugPrintOn: method and change the debugger to use this message, instead of #printOn: for displaying objects in inspector panels. Here is the default implementation of Object>>debugPrintOn: aStream ^ self printOn: aStream And, as you may guess, now the proxy could choose to behave differently depending on context. P.S. Maybe i'm missing a point, and there are already the existing good practices how to get around this.. if so, then please tell me. -- Best regards, Igor Stasenko AKA sig. |
>>>>> "Igor" == Igor Stasenko <[hidden email]> writes:
Igor> Here is the default implementation of Object> debugPrintOn: aStream Igor> ^ self printOn: aStream I like it, but I don't like the name. It conjurs up the idea of debugging the #printOn: method itself. maybe #printForDebuggerOn: ? -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <[hidden email]> <URL:http://www.stonehenge.com/merlyn/> Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion |
On 07.09.2009, at 18:40, Randal L. Schwartz wrote: >>>>>> "Igor" == Igor Stasenko <[hidden email]> writes: > Igor> Here is the default implementation of > > Object> debugPrintOn: aStream > Igor> ^ self printOn: aStream > > I like it, but I don't like the name. It conjurs up the idea of > debugging > the #printOn: method itself. > > maybe #printForDebuggerOn: ? It matches the other methods like #longPrintOn: though. Also that would imply only the debugger invokes it, when it's clearly appropriate for any purpose. However, apart from this bike shedding ;) do others think it's a good idea in general? IMHO #printOn: is primarily used for debugging anyway so I wouldn't really expect a separate debug print method to be needed. Debugging transparent proxies isn't for the faint-of-heart anyway, so these developers can adapt their tools and proxies I would guess. OTOH there is precedence in e.g. #asExplorerString, which exists solely to get rid of the quotes enclosing strings for aesthetic reasons ... - Bert - |
2009/9/7 Bert Freudenberg <[hidden email]>:
> > On 07.09.2009, at 18:40, Randal L. Schwartz wrote: > >>>>>>> "Igor" == Igor Stasenko <[hidden email]> writes: >> >> Igor> Here is the default implementation of >> >> Object> debugPrintOn: aStream >> Igor> ^ self printOn: aStream >> >> I like it, but I don't like the name. It conjurs up the idea of debugging >> the #printOn: method itself. >> >> maybe #printForDebuggerOn: ? > > > It matches the other methods like #longPrintOn: though. > > Also that would imply only the debugger invokes it, when it's clearly > appropriate for any purpose. > > However, apart from this bike shedding ;) do others think it's a good idea > in general? IMHO #printOn: is primarily used for debugging anyway so I > wouldn't really expect a separate debug print method to be needed. Debugging > transparent proxies isn't for the faint-of-heart anyway, so these developers > can adapt their tools and proxies I would guess. OTOH there is precedence in > e.g. #asExplorerString, which exists solely to get rid of the quotes > enclosing strings for aesthetic reasons ... > I agree with you Bert, that we should consider if its really necessary. While #printOn: is used by most code for debugging, some of the code using it to serialize object to textual stream, so the #printOn: usage is much more generic than just debugging. As for debugging the transparent proxies - yes you can make own tools.. but this means reimplementing/hacking other tools , like debugger, inspector and so on, which will probably end up with similar solution to what i proposing. For example, there was a point of discrepancy with debugging the code which uses Magma. The magma forwarding proxy reifying the object once the first real message is sent to it. And the problem with such a proxy, that you can't use them in certain situations, like: self perform: aSelectorProxied with: #foo because #perform doesn't sends the messages to aSelectorProxied and primitive fails. But then, when you entering the debugger and trying to figure out why its not working - a proxy becomes a real object when it printed out.. and so you can't debug the error using debugger. Which leaves you to wonder, why code works in debugger, but not working at run time :) > > - Bert - > -- Best regards, Igor Stasenko AKA sig. |
Magma is deliberate about printing proxy's:
MagmaMutatingProxy>>printOn: aStream MagmaPreferences debugProxies ifTrue: [ super printOn: aStream. aStream maPrint: $( ; maPrint: oid ; maPrint: '/' ; maPrint: session id ; maPrint: ')' ] ifFalse: [ self mutant printOn: aStream ] Making a new Proxy class can be tricky to debug, here are some tips I used in getting Magma's proxy's going. If you don't want a proxy to materialize: - use the inspector, not the explorer - if a particular proxy does not have a convenient type-checking test, you may print #class safely without materializing. - It's really easy to forget about robust printing methods, so when I had to debug proxy's I would generally avoid clicking state variables in the debugger variable lists, instead, send messages by typing only message-selectors I knew were available in the proxy class and "print it". I have actually been concerned about squirrelly debugging even for regular, non-proxy objects. It seems if you have too complex an expression; perhaps an exception handler wrapped in an ensure: within a critical: block, etc. that sometimes debugging "Through" those blocks results in a crashed debugger process. I can't remember the exact message at the moment, but it can be frustrating. I don't know that I've had the need or courage to step the debugger through a Proxy's #become:. Thankfully, once the proxy limitations are known, they are relatively easy to avoid. For example, when calling a primitive it is easy to include a #yourself: self perform: aSelectorProxied yourself with: #foo It's a chink the "transparency", thankfully the impact is negligible. I agree, use of == is generally bad form in applications, definitely not worth the very minor performance nick of the extra send to Object>>#=. Cheers, Chris On Mon, Sep 7, 2009 at 12:29 PM, Igor Stasenko<[hidden email]> wrote: > 2009/9/7 Bert Freudenberg <[hidden email]>: >> >> On 07.09.2009, at 18:40, Randal L. Schwartz wrote: >> >>>>>>>> "Igor" == Igor Stasenko <[hidden email]> writes: >>> >>> Igor> Here is the default implementation of >>> >>> Object> debugPrintOn: aStream >>> Igor> ^ self printOn: aStream >>> >>> I like it, but I don't like the name. It conjurs up the idea of debugging >>> the #printOn: method itself. >>> >>> maybe #printForDebuggerOn: ? >> >> >> It matches the other methods like #longPrintOn: though. >> >> Also that would imply only the debugger invokes it, when it's clearly >> appropriate for any purpose. >> >> However, apart from this bike shedding ;) do others think it's a good idea >> in general? IMHO #printOn: is primarily used for debugging anyway so I >> wouldn't really expect a separate debug print method to be needed. Debugging >> transparent proxies isn't for the faint-of-heart anyway, so these developers >> can adapt their tools and proxies I would guess. OTOH there is precedence in >> e.g. #asExplorerString, which exists solely to get rid of the quotes >> enclosing strings for aesthetic reasons ... >> > > I agree with you Bert, that we should consider if its really necessary. > While #printOn: is used by most code for debugging, some of the code > using it to serialize object to textual stream, so the #printOn: usage > is much more generic than just debugging. > > As for debugging the transparent proxies - yes you can make own > tools.. but this means reimplementing/hacking > other tools , like debugger, inspector and so on, which will probably > end up with similar solution to what i proposing. > > For example, there was a point of discrepancy with debugging the code > which uses Magma. > The magma forwarding proxy reifying the object once the first real > message is sent to it. > And the problem with such a proxy, that you can't use them in certain > situations, like: > > self perform: aSelectorProxied with: #foo > > because #perform doesn't sends the messages to aSelectorProxied and > primitive fails. But then, when you entering the debugger and trying > to figure out why its not working - a proxy becomes a real object when > it printed out.. and so you can't debug the error using debugger. > Which leaves you to wonder, why code works in debugger, but not > working at run time :) > >> >> - Bert - >> > > > -- > Best regards, > Igor Stasenko AKA sig. > > |
Free forum by Nabble | Edit this page |