[prev] [up]

Browsing a Snapshot Image

A SystemBrowser can also be opened on a previously saved snapshot image (via the FileBrowser's 'Snapshot Image Browser' menu item, or by evaluating:
    SystemBrowser openOnSnapShotImage:anImageFileName
This is a readOnly browser, which uses the information contained in the file instead of accessing class/method objects directly.

This browser is useful to extract code from old images - especially, if an old image is no longer executable, due to a recompilation of the ST/X executable.

How to perform typical day-to-day tasks

Creating a new class

If the new class is installed in a namespace AND hides a corresponding global class, methods within that namespace which access the class by its name are recompiled (possibly then accessing the new namespace-class).

Renaming a class

If the rename implies a change of the namespace, all methods which access the class by its old name are recompiled (possibly then accessing the previously hidden global class with the same name).
Do not rename classes programmatically, by changing a classes name and/or storing it under another key in the Smalltalk dictionary, because this will not take care of accessors and especially not recompile them.
(a program should use "Smalltalk renameClass:...to:", instead)

Removing a class

If the removed class was located in some namespace, and a global class exists with the same name (i.e. the class has hidden the global class within the namespace), all methods which access the class by its old name are recompiled (possibly then accessing the previously hidden global class).
Do not remove classes programmatically, by removing it from the Smalltalk dictionary, because this will not take care of accessors and especially not recompile them.
(a program should use "Smalltalk removeClass:...", instead)

Adding documentation

We suggest you stay with Smalltalk/X's philosophy of putting the documentation into empty methods under the 'documentation' category. To do so:

Adding methods

Modifying existing methods

"accept" installs whatever is currently visible; if the methods selector has been changed, a corresponding (possibly new) method will be generated - independent of the method which was selected in the first place.
Thus, you can select any other method, to take its source code as a starting point for new methods.

Removing methods

Notice, that the system cannot itself find out, if the method is still required - i.e. if there are any message sends which would possibly invoke that method (since message sends could be constructed by a #perform, or by evaluating a Smalltalk expression from a string).

Therefore, looking at all senders before actually removing any method may not always ensure that the method is not needed.
A good approach is to change the methods visibility to "ignored" instead of removing it. This marks the method as being invisible with respect to the method lookup - its still shown in the browser, but ignored by the program. Ignored methods may later be removed (or changed back to "public").

Adding/removing instance or class variables


existing instances of the class will not be affected by this change. Instead, the original class will get its category changed to "obsolete" and a new class is installed under the original name. This means, that existing instances still have a valid class definition around, but methods can no longer be added, removed or changed to the old class.
In case of a changed class definition (which affects the instance layout), the system will recompile all methods that require recompilation. Have a look at the Transcript, to see what is going on.
If the changed class has many subclasses, this may take a while, since all subclasses may have to be recompiled.

Who sends a particular message

Who implements a particular message

Which method is executed if I sent #foo

Use this to search up the class inheritance for an implementor of a particular message.

Which methods reference/modify a particular instance variable

A dialog appears, asking for the variables name (matchPatterns are allowed), and the set of classes to limit the search.

Since searching involves parsing the source code, these functions may take a while to show the result. Limiting the search to the current class or category helps here.

Simply selecting a variables name in this list will highlight all methods in which that variable is accessed.

Which methods reference a particular global variable


since classes are (almost) always referenced by globals, this will also find explicit uses of classes. (for example: try searching for "Array")

The outcome of the search will be presented in a browser, which has its search pattern preset to the globals name. Thus a search-next (i.e. "CMD-F") will place the cursor to the next occurence of the string.

Which methods use the current class

This menu function is just a shortcut for searching global references to the current classes name.

Which method contains some string

This question is often asked, if you have some method producing a message or output to some stream, and you want to find out quickly where that happens.
For example, which method is responsible for the "compiled: ..." message appearing on the transcript when methods are accepted.
There is no direct search function available for this kind of query. However, you can use the substring search functions to (at least) limit the number of methods that have to be investigated. Notice, that since all source code has to be processed, this function takes somewhat longer than other queries (senders/implementors); therefore, if you know the selector which is used, the senders function is probably better.
Also, if you have any idea of which class (or superclass) the method is contained in, limit the search to the current class or category.

Which message to use

Often, when you need some specific functionality, you know (or feel to know) that there must be some code for this in the system, but do not know exactly the name of the method.
For example, it may happen that you need some "string-concatenation" functionality, but do not remember what the message selector is.
To help in this situation, use the apropos function, which allows searching for a keyword in method selectors and method comments.
Try the above example, searching for 'concat'.

Notice, that this function too may take some time, since all source code has to be processed. You may limit the search to the current class or category.
In the above example, it seems obvious that concatenation is an operation on collections - therefore you could select the Collection class and do an apropos there (on all subclasses).

Which method contain a (specific) resource tag

For fast search, methods can be tagged with a "resource:" definition; this has no semantic meaning, but methods tagged this way can be quickly found, without a need to scan its source (there is a corresponding resource-tag-bit in the method object, which is much faster to check).

Within ST/X, methods are marked with the following tags:

Therefore, to find all methods which do keyboard event handling, search for a resource named "keyboard".

You may either search for a resources key (as above) or for some particuler value item; for example, all methods which handle the "Accept" key are found by a search for the resource "keyboard" and a value of "Accept".

You can mark your methods with any resource; for example, in a project it may be useful to tag methods with things like "toBeReviewed", "toBeTested", "preliminary" or whatever.
These methods are later quickly found by searching for an appropriate resource.

Sorry, there is no resource search menu item in the browser; instead, the launcher offers this in its classes pull down menu.

Changing a classes namespace

This is done by renaming the class, prepending the namespace-prefix to the new name.
For example, to move a class called "Foo" into the "MyPrivateClasses" namespace, simply rename the class to "MyPrivateClasses::Foo".

The rename dialog is found in the classLists popUpMenu.

Changing a classes category

Get the classes definition (by reselecting the class, or toggling one of the class/instance toggles), change the string after the category argument and accept.

Special search browsers

You can start a browser manually, and pass a searchBlock (which is supposed to return true/false) to open a browser on any subset of methods. Currently, there is no special menu item for this, so you have to enter an expression into a workspace, and evaluate it there.

For example, a browser on all methods with 3 arguments can be opened with:

    SystemBrowser browseAllSelect:[:cls :method :sel |
					sel numArgs == 3
if you are interested in methods with more than 10 arguments, try:
    SystemBrowser browseAllSelect:[:cls :method :sel |
					sel numArgs > 10
or, to find all methods which have 'at:' in their name:
    SystemBrowser browseAllSelect:[:cls :method :sel |
					'*[aA]t:*' match:sel
Beside browseAllSelect:, there are other special startup messages to be found in SystemBrowsers class protocol. Have a look at them - you may find some of them useful when searching for methods.

Extra hint:
The Launcher's class menu offers an item to open a browser on all methods which access a particular resource. Since resource-access is defined symbolically (with a Resource directirve in the method), any arbitrary symbol can be used there. For example, you can mark your method with:

    <Resource: #toBeRevieved>
and find all methods which need a review by entering "toBeRevieved" as as the resource you are looking for. (of course, you can also use the browser's string search function - but that is much slower, since all of the systems sourceCode has to be investigated ...)

Hints & tips

Mark your changed methods

when adding methods to existing system classes, you should mark them (either by name or their category) to ease finding those later.
For example, you may later want to fileout all of your added methods. This can be done automatically if all of them have a distinct category. ("fileOut-all" function in the method category list).

Starting with version 2.10.4, methods and classes include a package field. This makes it very easy, to identify classes and methods which belong to a package for fileOut. Set the current projects packageName to some unique name and use the ProjectViews "browse" function to see what has been changed within that project. There are also menu functions to selectively fileOut per-project changes to your projects directory.

Prepare use of the stc machine code compiler

If you plan to compile your classes later to binary modules, use the "fileout-each" function instead of "fileOut" in the class category list.
This one will create separate sourcefiles for each class instead of putting all of them into one big file. The reason is that the stc-compiler (currently) cannot compile multiple classes, but requires one class per sourcefile.

Use project directories

If you are working in multiple projects, define some per project directory in the project view. The systemBrowser will always save files into the active projects directory.
This avoids having all of your filedOut sourcefile being saved in one big directory, and helps to structure your project.

Keep your sourcefiles consistent

Be careful about overwriting existing sourcefiles when filing out: since the methods source is typically extracted from some sourcefile, overwriting one of tme will lead to funny results. All fileOut functions will be changed in upcoming versions to take care about this, but currently you should never fileOut into the "source" or one of the "libXXX" directories.

Be very careful when editing existing sourcefiles with the fileBrowser or another (non-ST/X) editor. Since methods do not keep the source as a string (but instead the filename and filePosition), editing a sourcefile makes this sourceInfo invalid (you will see funny code in the systemBrowser) in the current Smalltalk executable.
You have to recompile that file and relink a new Smalltalk executable to fix things.

If you see funny sourcecode in the browser, do NEVER fileOut these - the resulting sourcefile may be completely useless.

The above consistency problem does not apply, if the sourceCode manager is used; if enabled, the sourceCode manager can figure out the classes actual version, and extract the corresponding source version from the repository - even if newer versions of the same class are present in local source files or in the repository.

The sourceCode manager is only provided with the commercial release - therefore, demo-version and private-version users should be very careful.

Doc $Revision: 1.19 $ $Date: 2016/09/14 09:41:13 $