Another reason I like Squeak: Introspection

Tim Olson tim at jumpnet.com
Sun May 31 22:51:47 UTC 1998


It's wonderful that the Squeak sources are fully open and easily 
browsable.  But even more than that, Squeak's runtime is open to browsing 
(and possible modification) through introspection.

Normally introspection is reserved for things like Debuggers, but here's 
a case where I used the facility to my advantage:

I needed to FTP a fairly large file from a server.  Since I was working 
in Squeak at the time, I figured I would do the FTP in Squeak, writing 
out the contents to a file when it was complete.  A couple minutes later, 
after browsing the FTPSocket sources, I had an FTP process running in the 
background.

After it had been running for a bit, I realized that it would be nice to 
have some sort of visual indication of the FTP progress.  However, 

     a) I didn't want to clutter up the existing FTPSocket code with a
        progress display (*), and

     b) I didn't want to stop and restart the transfer, in any case.

Looking again at the FTPSocket sources, I discovered that what I wanted 
was the position of the stream stored in the temporary variable 
'response' in the method #getAllDataWhileWatching:

Since *everything* in Squeak is an object, including the runtime contexts 
of the various running processes, I was able to do the following on the 
already running ftpProc:

     ctxt := ftpProc suspendedContext.
     [ctxt method == (FTPSocket compiledMethodAt: 
#getAllDataWhileWatching:)] whileFalse:
	    [ctxt := ctxt sender].

This followed up the ftpProc's context chain until it found the context 
which was executing in the #getAllDataWhileWatching: method. Then, to get 
the value of the 'response' temporary variable in that context, I 
executed:

     resp := ctxt tempAt: (ctxt tempNames indexOf: 'response').

Then all I needed to do was periodically send 'position' to the resp 
stream to find out how much data had been transferred:

     oldSize := newSize := 0.
     'FTP status:'
	         displayProgressAt: (Display width - 96) @ 64
	         from: 0 to: ftpSize
	         during:
		             [:bar |
		             oldSize := newSize.
		             newSize := resp position.
		             [oldSize ~= newSize] whileTrue:
                    [bar value: newSize.
                    (Delay forSeconds: 30) wait]].


(*) after succesfully doing this, I started thinking about the 
user-interface ramifications of String>>displayProgressAt:  It's a handy 
thing, but it puts the user at the whim of the person who coded it in, 
and since it is statically associated with the method, rather than some 
dynamic form of progress display control, if it isn't what the caller 
wants displayed, it can't easily be modified.  For example, the recent 
suggestions that the automatic server update progress show the progress 
of the entire transfer, rather than the individual streams.

I wonder if some form of dynamic registry for progress indication, 
perhaps something like how error handling is registered, might be 
something to explore.



     -- tim





More information about the Squeak-dev mailing list