Pretty print any object... got a good snippet?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Pretty print any object... got a good snippet?

Matthew Boulter
Hi all,
I'm reverse engineering a complex aspect of our Smalltalk application (no docs :( ).
In this sort of exercise I am a big fan of being able to pretty print the 'state' of an object at various points in the code.

I don't want to inspect live, I need it logged.

Save me sitting down and writing such a thing.

Got any good code snippets or suggest a class that's up my alley.

Appreciated. 

Regards, Matt.

--
You received this message because you are subscribed to the Google Groups "VAST Community Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/va-smalltalk/CAHC26T78uhe2pU%3Dhg%3D2-Tvjn%2BWnKkE%2BWYzdf_%3D41%3DSb_3yLQXQ%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Pretty print any object... got a good snippet?

Louis LaBrunda
Hi Matt,

I'm not sure if this is what you are looking for or if you already know about it but here goes.  Many if not most classes have the #printOn: method where they print much of their internals on a stream.  If you send an instance #printString, a stream is created, #printOn: is sent with the stream and the contents of the stream are returned as a string.  If your classes don't have #printOn:, you should write it for those you are interested in.  You don't need to write #printString as #Object already has it and it will use your #printOn: method.  This is also used (in part) when you inspect instances.

Lou

On Wednesday, May 5, 2021 at 5:59:50 AM UTC-4 [hidden email] wrote:
Hi all,
I'm reverse engineering a complex aspect of our Smalltalk application (no docs :( ).
In this sort of exercise I am a big fan of being able to pretty print the 'state' of an object at various points in the code.

I don't want to inspect live, I need it logged.

Save me sitting down and writing such a thing.

Got any good code snippets or suggest a class that's up my alley.

Appreciated. 

Regards, Matt.

--
You received this message because you are subscribed to the Google Groups "VAST Community Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/va-smalltalk/40d29e9c-46b7-486b-a9d8-78dab785c673n%40googlegroups.com.
Reply | Threaded
Open this post in threaded view
|

Re: Pretty print any object... got a good snippet?

Mariano Martinez Peck-2
Hello Matt, 

You may want to take a look to #storeString. It prints all the instVars in a way that you can "do it" and get back an object equal to the original. 
For example, "Locale current lcTime storeString" prints:

'((LCTime basicNew)
instVarAt: 1 put: ((Array basicNew: 7)
at: 1 put: ''Sun'';
at: 2 put: ''Mon'';
at: 3 put: ''Tue'';
at: 4 put: ''Wed'';
at: 5 put: ''Thu'';
at: 6 put: ''Fri'';
at: 7 put: ''Sat'';
yourself);
instVarAt: 2 put: ((Array basicNew: 7)
at: 1 put: ''Sunday'';
at: 2 put: ''Monday'';
at: 3 put: ''Tuesday'';
at: 4 put: ''Wednesday'';
at: 5 put: ''Thursday'';
at: 6 put: ''Friday'';
at: 7 put: ''Saturday'';
yourself);
instVarAt: 3 put: ((Array basicNew: 12)
at: 1 put: ''Jan'';
at: 2 put: ''Feb'';
at: 3 put: ''Mar'';
at: 4 put: ''Apr'';
at: 5 put: ''May'';
at: 6 put: ''Jun'';
at: 7 put: ''Jul'';
at: 8 put: ''Aug'';
at: 9 put: ''Sep'';
at: 10 put: ''Oct'';
at: 11 put: ''Nov'';
at: 12 put: ''Dec'';
yourself);
instVarAt: 4 put: ((Array basicNew: 12)
at: 1 put: ''January'';
at: 2 put: ''February'';
at: 3 put: ''March'';
at: 4 put: ''April'';
at: 5 put: ''May'';
at: 6 put: ''June'';
at: 7 put: ''July'';
at: 8 put: ''August'';
at: 9 put: ''September'';
at: 10 put: ''October'';
at: 11 put: ''November'';
at: 12 put: ''December'';
yourself);
instVarAt: 5 put: ''%l:%M:%S %p %z/%f/%Y'';
instVarAt: 6 put: ''%z/%f/%Y'';
instVarAt: 7 put: ''%l:%M:%S %p'';
instVarAt: 8 put: ((Array basicNew: 2)
at: 1 put: ''AM'';
at: 2 put: ''PM'';
yourself);
instVarAt: 9 put: ''%l:%M:%S %p'';
instVarAt: 10 put: ((Array basicNew: 7)
at: 1 put: #''format_l:date:time:'';
at: 2 put: '':'';
at: 3 put: #''format_M:date:time:'';
at: 4 put: '':'';
at: 5 put: #''format_S:date:time:'';
at: 6 put: '' '';
at: 7 put: #''format_p:date:time:'';
yourself);
instVarAt: 11 put: ((Array basicNew: 5)
at: 1 put: #''format_z:date:time:'';
at: 2 put: ''/'';
at: 3 put: #''format_f:date:time:'';
at: 4 put: ''/'';
at: 5 put: #''format_Y:date:time:'';
yourself);
instVarAt: 12 put: ((Array basicNew: 13)
at: 1 put: #''format_l:date:time:'';
at: 2 put: '':'';
at: 3 put: #''format_M:date:time:'';
at: 4 put: '':'';
at: 5 put: #''format_S:date:time:'';
at: 6 put: '' '';
at: 7 put: #''format_p:date:time:'';
at: 8 put: '' '';
at: 9 put: #''format_z:date:time:'';
at: 10 put: ''/'';
at: 11 put: #''format_f:date:time:'';
at: 12 put: ''/'';
at: 13 put: #''format_Y:date:time:'';
yourself);
yourself)'



So...with objects with long collections this method may be too much, but I just wanted to share it with you in case it could work as a first step. 

Best, 

Mariano


On Wed, May 5, 2021 at 8:48 AM Louis LaBrunda <[hidden email]> wrote:
Hi Matt,

I'm not sure if this is what you are looking for or if you already know about it but here goes.  Many if not most classes have the #printOn: method where they print much of their internals on a stream.  If you send an instance #printString, a stream is created, #printOn: is sent with the stream and the contents of the stream are returned as a string.  If your classes don't have #printOn:, you should write it for those you are interested in.  You don't need to write #printString as #Object already has it and it will use your #printOn: method.  This is also used (in part) when you inspect instances.

Lou

On Wednesday, May 5, 2021 at 5:59:50 AM UTC-4 [hidden email] wrote:
Hi all,
I'm reverse engineering a complex aspect of our Smalltalk application (no docs :( ).
In this sort of exercise I am a big fan of being able to pretty print the 'state' of an object at various points in the code.

I don't want to inspect live, I need it logged.

Save me sitting down and writing such a thing.

Got any good code snippets or suggest a class that's up my alley.

Appreciated. 

Regards, Matt.

--
You received this message because you are subscribed to the Google Groups "VAST Community Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/va-smalltalk/40d29e9c-46b7-486b-a9d8-78dab785c673n%40googlegroups.com.


--

Mariano Martinez Peck

Senior Software Engineer

 [hidden email]
 @MartinezPeck
 /mariano-martinez-peck
 instantiations.com
TwitterLinkedInVAST Community ForumGitHubYouTubepub.dev

--
You received this message because you are subscribed to the Google Groups "VAST Community Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/va-smalltalk/CAOUkibFBNqHBN0gw6f60W58kHDjKTwrSqJmxckzFc2x-HeuGrQ%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Pretty print any object... got a good snippet?

thomas....@natural-software.eu
I don't know about your specific requirement but I just want to share an approach that I found quite useful in difficult debugging situations.

The method markReadOnly: sets an object to call the method "attemptedROMStore:intoSlot:" when an instance variable of an object gets changed.

Thus, if you have an own object model of e.g. business objects you can use this approach to determine when someone changes an instance variable in an object in an unexpected way. Just implement this method in a subclass and you know when someone changes the object. If you do not want to disturb the flow in your program, then resetting markReadOnly in this method lets you write the new contents to an instance variable.

If "attemptedROMStore:intoSlot:" cannot be subclassed, you can always use an exception handler in order to get to the difficult location.

So for example:

| aObj assoc |
aObj :=Dictionary new.
aObj at: #A2 put: 'Hallo'.
assoc := aObj associationAt: #A2 ifAbsent:[].
assoc markReadOnly: true.
[
 aObj at: #A2 put: 'This will not be set into the object'.
] when: ExError do: [:sig |
sig arguments first = 'Store into read-only object' ifTrue: [
Transcript show: 'Read only object has been changed. Do perhaps a stack dump to see where the change comes from ??'; cr.
].
sig exitWith: nil.
].

And of course - this type of coding is for debugging purposes only. 


[hidden email] schrieb am Mittwoch, 5. Mai 2021 um 13:57:17 UTC+2:
Hello Matt, 

You may want to take a look to #storeString. It prints all the instVars in a way that you can "do it" and get back an object equal to the original. 
For example, "Locale current lcTime storeString" prints:

'((LCTime basicNew)
instVarAt: 1 put: ((Array basicNew: 7)
at: 1 put: ''Sun'';
at: 2 put: ''Mon'';
at: 3 put: ''Tue'';
at: 4 put: ''Wed'';
at: 5 put: ''Thu'';
at: 6 put: ''Fri'';
at: 7 put: ''Sat'';
yourself);
instVarAt: 2 put: ((Array basicNew: 7)
at: 1 put: ''Sunday'';
at: 2 put: ''Monday'';
at: 3 put: ''Tuesday'';
at: 4 put: ''Wednesday'';
at: 5 put: ''Thursday'';
at: 6 put: ''Friday'';
at: 7 put: ''Saturday'';
yourself);
instVarAt: 3 put: ((Array basicNew: 12)
at: 1 put: ''Jan'';
at: 2 put: ''Feb'';
at: 3 put: ''Mar'';
at: 4 put: ''Apr'';
at: 5 put: ''May'';
at: 6 put: ''Jun'';
at: 7 put: ''Jul'';
at: 8 put: ''Aug'';
at: 9 put: ''Sep'';
at: 10 put: ''Oct'';
at: 11 put: ''Nov'';
at: 12 put: ''Dec'';
yourself);
instVarAt: 4 put: ((Array basicNew: 12)
at: 1 put: ''January'';
at: 2 put: ''February'';
at: 3 put: ''March'';
at: 4 put: ''April'';
at: 5 put: ''May'';
at: 6 put: ''June'';
at: 7 put: ''July'';
at: 8 put: ''August'';
at: 9 put: ''September'';
at: 10 put: ''October'';
at: 11 put: ''November'';
at: 12 put: ''December'';
yourself);
instVarAt: 5 put: ''%l:%M:%S %p %z/%f/%Y'';
instVarAt: 6 put: ''%z/%f/%Y'';
instVarAt: 7 put: ''%l:%M:%S %p'';
instVarAt: 8 put: ((Array basicNew: 2)
at: 1 put: ''AM'';
at: 2 put: ''PM'';
yourself);
instVarAt: 9 put: ''%l:%M:%S %p'';
instVarAt: 10 put: ((Array basicNew: 7)
at: 1 put: #''format_l:date:time:'';
at: 2 put: '':'';
at: 3 put: #''format_M:date:time:'';
at: 4 put: '':'';
at: 5 put: #''format_S:date:time:'';
at: 6 put: '' '';
at: 7 put: #''format_p:date:time:'';
yourself);
instVarAt: 11 put: ((Array basicNew: 5)
at: 1 put: #''format_z:date:time:'';
at: 2 put: ''/'';
at: 3 put: #''format_f:date:time:'';
at: 4 put: ''/'';
at: 5 put: #''format_Y:date:time:'';
yourself);
instVarAt: 12 put: ((Array basicNew: 13)
at: 1 put: #''format_l:date:time:'';
at: 2 put: '':'';
at: 3 put: #''format_M:date:time:'';
at: 4 put: '':'';
at: 5 put: #''format_S:date:time:'';
at: 6 put: '' '';
at: 7 put: #''format_p:date:time:'';
at: 8 put: '' '';
at: 9 put: #''format_z:date:time:'';
at: 10 put: ''/'';
at: 11 put: #''format_f:date:time:'';
at: 12 put: ''/'';
at: 13 put: #''format_Y:date:time:'';
yourself);
yourself)'



So...with objects with long collections this method may be too much, but I just wanted to share it with you in case it could work as a first step. 

Best, 

Mariano


On Wed, May 5, 2021 at 8:48 AM Louis LaBrunda <[hidden email]> wrote:
Hi Matt,

I'm not sure if this is what you are looking for or if you already know about it but here goes.  Many if not most classes have the #printOn: method where they print much of their internals on a stream.  If you send an instance #printString, a stream is created, #printOn: is sent with the stream and the contents of the stream are returned as a string.  If your classes don't have #printOn:, you should write it for those you are interested in.  You don't need to write #printString as #Object already has it and it will use your #printOn: method.  This is also used (in part) when you inspect instances.

Lou

On Wednesday, May 5, 2021 at 5:59:50 AM UTC-4 [hidden email] wrote:
Hi all,
I'm reverse engineering a complex aspect of our Smalltalk application (no docs :( ).
In this sort of exercise I am a big fan of being able to pretty print the 'state' of an object at various points in the code.

I don't want to inspect live, I need it logged.

Save me sitting down and writing such a thing.

Got any good code snippets or suggest a class that's up my alley.

Appreciated. 

Regards, Matt.

--
You received this message because you are subscribed to the Google Groups "VAST Community Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/va-smalltalk/40d29e9c-46b7-486b-a9d8-78dab785c673n%40googlegroups.com.


--

Mariano Martinez Peck

Senior Software Engineer

 [hidden email]
 @MartinezPeck
 /mariano-martinez-peck
 instantiations.com
TwitterLinkedInVAST Community ForumGitHubYouTubepub.dev

--
You received this message because you are subscribed to the Google Groups "VAST Community Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/va-smalltalk/24425dd8-6818-4d1e-bd92-47b59621fd8cn%40googlegroups.com.