Using the System Browser
SystemBrowsers are the main tool for programming in smalltalk;
they allow you to both browse through the system, search for methods and
to create, modify or remove classes and methods.
The standard System Browser consists of 5 major subviews; the interresting components are:
- class category list
- class list
- class/instance toggle
- method category list
- method list
- code view
Within the system, all classes are assigned to a class category,
this category has NO semantic function of any kind, it is simply
an attribute, to group classes for easier handling.
(actually, beside the browser, there are not many uses of class categories.)
Once a class category is selected (by clicking on the entry in the
class category list), the class list shows all classes belonging to
that category.
The systemBrowser also offers two "special" categories:
"* all *"
which will display all classes and show them alphabetically,
and
"* hierarchy *"
which also displays all classes, but shows them as a tree (by inheritance).
Selecting a class in the class list, will show all method categories
in the method category list.
Like class categories, method categories are only used
for grouping related methods; typically, methods are categorized
by function or effect. Like class categories, these have no semantic effect.
Selecting a method category will show all methods in that category.
The special category
"* all *"
shows all methods in alphabetic order.
Finally, selecting a method in the method list will show the corresponding
methods source code in the code view.
Notice that, if the classes source file has been removed, or is not accessable,
the codeview will show the string "no source available"
.
Also keep in mind, that these lists (like all selection lists) respond to keyboard events:
especially, alpha-keys (search for the next entry with that character),
cursor up/down, pageup/pagedown, home and end-keys
are useful for navigation.
For examples on
typical uses of the browser,
see the last section(s) of this document.
The browser allows working on both a class and its metaclass (i.e. the
classes class). Smalltalk beginners should keep in mind, that classes are
objects like anything else in the system - and thus their behavior is described
by a class (so called metaclass). The set of messages understood by instances of a
class is called "instance protocol", while the set of messages understood by the class
is called the "class protocol".
Just like instances inherit protocol from the superclass, class protocol is inherited
from the metaclasses superclass.
To switch, there are two toggle buttons named "class"
and
"instance"
.
Selecting "instance"
(which is the default) makes your changes
affect the class, while selecting "class"
makes them affect the metaclass.
Each of the views provides its own middle button popup menu - activated by
pressing the middle mouse button (the right button if you use a 2-button mouse).
The class category list provides the following menu functions:
- fileOut
- save all classes in the currently selected
class category into one big source file.
The file will be named
"categoryName.st"
and contain the code such that it can be
reloaded later or on another system
(see FileBrowsers
"fileIn"
function).
The format in which the code is saved is compatible
to Smalltalk-80's fileOut format.
The file is created in the current project-directory (see
projects ).
- fileOut each
- save all classes, but put each class into a
separate file, named
"className.st"
.
The files are created in the current project directory.
(see projects)
- printOut
- sends a printed representation of all classes
in the selected category to the printer.
The printout includes each methods source code.
- printOut protocol
- sends a short protocol-only printed representation
of all classes in the selected category to the
printer. The printout will not include the methods
code, but the methods selector and the first comment
found in the method - a format which is very valuable for
documentation purposes.
- spawn
- starts a class category browser on the currently
selected class category. This is a browser without
the class category list (try and see).
- spawn class
- starts a full class browser.
A full class browser allows editing the whole classes
code in one view - this is very handy, if changes
to many methods are to be done - especially if those
changes depend on each other (for example, to rename
a methods selector or a variables name).
- update
- will rescan all classes in the system and update the lists shown.
Normally, the systemBrowser tries itself to keep track of changes done by
other parts of the system; however, there are situations, in which the browser
does not get notified of these and needs a manual update.
- find class
- pops up a box to enter the name of a class.
This class will be searched for and selected.
The entered string may include wildcard characters.
For example, it is possible to search for all classes
containing the substring
"Collection"
in their name by
entering "*Collection*"
.
No action is performed, if the entered class does not
exist.
- new class category
- allows creation of a new class category. Notice, that the new
category will become persistent only after a class has
been created with that category.
- rename
- rename a category. This will change the class category
attribute of all classes in the currently selected
class category.
- remove
- remove all classes (& subclasses) in the current class
category. You will be warned by a popup box which has
to be answered positively, for the deletion to be
actually performed.
Most functions in the class lists popupmenu affect the currently selected class.
It provides the following operations:
- fileOut
- save the currently selected classes source code
in a file named
"className.st"
.
The file is created in the current project directory.
- printOut
- send the currently selected classes source code to the printer.
- printOut protocol
- send the currently selected classes protocol
description to the printer. This output will contain
the class description, class comment and the classes
protocol, including method comments.
- spawn
- start a single class browser on the currently selected
class (try and see)
If the codeview has a valid className highlighted
(i.e. selected), a browser is spawned on that class.
- spawn hierarchy
- start a hierarchy browser on the currently selected
class, all of its superclasses and all subclasses.
If the codeview has a valid className selected,
a hierarchy browser is spawned on that class.
- spawn subclasses
- start a browser on all subclasses of the currently
selected class.
(this includes subclasses of subclasses etc).
If the codeview has a valid className highlighted,
a subclass browser is spawned on that class.
- hierarchy
- show the hierarchy of the currently selected class in
the code view. If the class-toggle is pressed, the
metaclass hierarchy is shown.
- definition
- shows the classes definition in the codeview.
Editing the definition and
"accepting"
in the code view
allows changing the classes definition (i.e. inheritance, instance variables
and category).
- comment
- shows the class comment in the code view.
Editing the comment and
"accepting"
allows changing the classes comment.
- class instvars
- shows the classes class-instance-variables in the code
view.
Editing and
"accepting"
in the code view allows
changing the classes instance variables.
Do not confuse class-instance-variables with class-variables -
see the Smalltalk language documentation for this.
- class refs
- searches for uses of the selected class, and
opens a browser on all referencing methods.
This is the same as the
globals
function in
the method-menu; it has been added for the convenience
of ST-80 users.
- variable search
- this entry provides access to a submenu offering
searches for different variable references.
After the search, another browser showing all methods
referencing the variable of interrest.
The search can be for any reference or modifying references.
You may either search locally (in the selected class only)
or over the whole tree of subclasses.
You may use wildcards when searching.
Notice, that this search may take some time, the system
has to parse the source of all involved methods to find
these accesses.
If no method is found referencing the variable, the
Transcript
will show a short message ("none found").
- new class
- shows a new class definition prototype in the code view.
You should edit this template, by changing the classes
name and filling in the instanceVariables and/or classVariable names.
"accepting"
in the code view will actually create the
new class.
- new subclass
- same as new class, but the offered class definition
will be for a subclass of the currently selected class.
- rename
- change the name of the currently selected class.
Since this class may be referenced by other code in the
system, all references to that class are searched for
and shown in another browser - you should then decide
if those references should be changed or not
(edit those references and
"accept"
in this new
browsers code view).
- remove
- will remove the currently selected class and all of its
subclasses. You will get a chance to cancel, if
you changed your mind.
The method category list provides the following menu functions:
- fileOut
- save the currently selected method categorys source
code in a file named
"className-category.st"
.
The file is created in the current project directory.
Not very useful - except to transfer parts of a class
to others.
- fileOut all
- save all methods which have the same category as the
currently selected method category in a file named
"category.st"
.
The file is created in the current project directory.
- printOut
- print all methods of the currently selected category.
- spawn
- start a method category browser on all methods in the selected category (try and see).
- spawn category
- start a browser on all methods (i.e. of all classes)
which have the same method category as the currently
selected one (try and see).
- find method here
- allows searching for the method implementing a selector.
The selector has to be entered into a box - wildcards
are allowed.
No action is performed, if there is no method
implementing that selector.
- find method
- same, but searches up in the class hierarchy for the
first class implementing the selector. This answers the
question "when I send #foo to instances of this class,
which method gets evaluated ?"
No action is performed, if there is no method
implementing that selector.
- new category
- addes a new category to the list. For this new category
to become persistent, at least one method must exist
with this category attribute.
- copy category
- allows copying all methods within another classes category to
the currently selected class. You can specify wildcards
in the category name.
For example, entering
"*"
as category, will copy all methods from
the other class. This function is very useful if you want to copy a class
(for example, to experiment with a modified system class).
- create access methods
- creates methods to access instance variables.
For each instance variable foo, two methods are created:
#foo
- which returns this instance variable
and:
#foo:
- which sets this instance variable
This function is non-destructive: if a method by that
name already exists, it is not overwritten or changed.
- rename
- rename the method category
- remove
- remove all methods (in the currently selected class
only) which are members of the selected method category.
You will be asked before the remove is actually
performed.
The method list provides the following menu functions:
- fileOut
- save the currently selected method in a file named
"className-selector.st"
.
The file is created in the current project directory.
Not very useful - except to transfer individual methods
to others.
- printout
- send a printed representation of the currently selected
method to the printer.
- spawn
- start a browser for editing this method only.
If a string of the form
"classname>>selector"
is selected
in the codeview, a browser is opened on that method.
Some method comments contain this kind of cross-reference
to allow quick start of a browser.
- senders
- starts a new browser on all methods sending a specific
message. The message selector can be entered in a box,
the browser offers a reasonable default,
which is the current methods selector or the selection in the code view.
If the code views selection consists of a code fragment, the browser tries to extract
the selector (try & see).
- implementors
- starts a new browser on all methods implementing a
specific message.
The same selection mechanism as in
"senders"
is used.
- globals
- starts a new browser on all methods accessing a global
- local sender
- same as
"senders"
, but limits the search to the current class and its subclasses.
- local implementors
- same as
"implementors"
, but limits the search to the current class and its subclasses.
- breakpoint
- sets a breakpoint on the selected method. The
debugger will be entered, whenever a breakpointed method
is about to be executed. A single step or continue
will then actually start execution of the method.
- trace
- turns on tracing of the selected method. Traced methods
will output some information on the standard-error
(Stderr) both on entry and exit.
To trace into a file, Stderr should be set to some
fileStream opened for writing.
- trace sender
- turns on sender-tracing of the selected method. Like
trace, but only a short note identifying the sender of
the method will be written to Stderr.
- remove break/trace
- remove breakpointing or tracing of the selected method.
Any trace- or breakpoint is also removed, whenever the
current method is recompiled (i.e.
"accepted"
).
- new method
- shows a method template in the code view. You should
edit this template and
"accept"
in the code view.
Actually, this template is simply a reminder on method syntax.
To create a method, it is sufficient to "accept"
in the code view with any method category
selected. (i.e. just edit and "accept"
)
Typically new methods are created by copying some existing
code into an empty codeview, then the selector and code
are modified as needed, and finally "accepted"
.
- change category
- allows putting the currently selected method into another category
(i.e. change the category of the selected method)
- remove
- removes the currently selected method. No confirmations are asked for.
Selecting the "accept"
in the code views popup menu performs an action depending on what the
last action was in one of the list views. In general, "accept"
always affects
the aspect shown last in the code view. This means that "accept"
changes:
- the class comment
after you selected "comment"
in the class menu
- the class definition
after you changed classes, or selected "definition"
in the class menu.
- the classes
class-instance-vars - after selecting "class instvars"
- the methods definition
after changing methods or selecting "new method"
in the method menu.
The one exception is the full class browser: "accept"
may affect all of the
above, since it rereads all of the text shown in the codeview (actually a filein).
Unless your changed code has been "accepted"
, no changes are made to the actual
method or class. If you want to change your mind, and go back to the original
(actually: the last "accepted"
) version after editing for a while, simple click
on the method (in the methodlist) after a method change or the class
(in the classList) after a definition change.
Changing a classes instance- or classInstance variable definition may require a
recompile of some or all methods (also often in subclasses).
Smalltalk tries to recompile only the minimum set of methods, but still this
recompilation may take some time.
Notice, that when you add or remove instance variables to/from a class description
and "accept"
, the system will actually create a new class instead of changing
the old one (this is also true for class instance variables).
The original class is still physically around, but no longer accessable by name.
It is called an anonymous class and has a category of "obsolete"
.
The reason for doing this is that existing instances of the class still need their valid
class for proper operation (which is the old one, NOT the new one); keep in mind that
all specification (i.e. number of instance variables etc.) and protocol (i.e. the list of
selectors) are defined in an objects class - therefore, old instances would be in big trouble
without a valid class, once they receive a message.
After such a change, the old (anonymous) class is no longer editable by the
systemBrowser. The following scenario should give you more insight on this:
consider a view class of yours,
of which an instance exists and is visible on the screen
now you add an instance variable "foo"
to its class description
this creates a new class (with the original name), and removes the
old one from the name tables; the old class is still around but not
reachable by the old name. However, if you inspect that class, it will
show its old name and a category of "obsolete
.
Old instances are therefore no longer affected by any changes in the browser,
thus any changes will only make sense for new instances.
Why is this so ?
There are basically 2 other possible solutions to handling this situation:
- do not allow a class definition change as long as there are instances
this would make it impossible, to change things like ScrollBars, TextViews
and almost any other class in the system.
- convert instances
this means that existing instances have to either get
new fields added (which default value ?) or instance variables removed.
In theory, this is possible and may be offered in a later release as an
option.
Notice:
sometimes, it happens that browsers do not correctly update after such
a definition change (i.e. a class definition is changed in one browser, but
other browser(s) continue to show the old, obsolete class.
You will notice this when adding new methods, which do not show up in other
browsers.
To prevent confusion, it is a good idea to use the "update"
menu function of
other browsers - or start a browser if you are in doubt.
This is definitely a bug in ST/X and will be fixed.
Especially beginners should not change the definition of any existing class, but
stick to their private ones. (even 'gurus' think twice before doing that :-)
The "copy category"
function is very helpful when creating experimental versions
of new classes - it allows a very quick class duplication.
So, instead of modifying any existing class, its better to create a new one and
copy all methods over from the original one.
Then test & debug the new class until perfect.
When done, you can override the old one with the class "rename"
function.
This approach is especially suggested when you modify classes which are used by
the system itself, since bugs in those may lead to subtile errors or even crashes.
(just consider modifying ScrollBar to make it err somewhere; since the Debugger
uses scrollBars too, it will have problems coming up. As a result, you will
might to quit smalltalk and restart your session).
Sometimes the browser will show funny source code in the codeview (totally
wrong, empty code or off by some characters). This happens, when a sourcefile
has been changed or removed from outside the browser (i.e. with FileBrowser or
any other editor/program) and the smalltalk system has not been recompiled or
relinked yet (i.e. the compiled class in the executable is not up-to-date).
Since the source information in a method is simply the filename+filePosition,
this in-memory information is wrong after such a change.
A recompile (using stc
) followed by a relink of the smalltalk executable, should
give you a version with correct (up-to-date) source information.
creating a new class
- select the class category, where the new class shall be included in
(if you want to add a new category, use the
"new class category"
menu
function in the class category list).
- select the menu function
"new class"
in the class list
This will show a class definition template in the codeview.
- edit the template (change the superclasses name, your classes name
and add instance and/or class variables if any).
"accept"
(use the "accept"
menu function in the codeview)
adding methods
- select the class
- select the method category (or create a new method category, by
using the
"new category"
menu function in the method category list)
- type in the method into the codeview
You can also get a method template with the "new method"
menu function in the method lists popup menu. Alternatively, copy&paste some
code from any other textView, and modify it as appropriate.
"accept"
modifying existing methods
- select class, method category and method; this will bring the
methods source into the codeview.
- edit the methods code as required
-
"accept"
removing methods
- select class, method category and method; this will bring the
methods source into the codeview.
- use the
"remove"
function from the method lists popup menu
adding/removing instance variables
- select the class (this will show its definition in the codeview)
- edit the
'instanceVariableNames'
or 'classVariableNames'
-string
as required.
-
"accept"
Notice:
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 re-
compilation. Have a look at the Transcript, to see what is going on.
who sends a particular message
- activate the
"senders"
function in the method menu
- fill in selector to search for. You can use wildcards (i.e. a matchpattern).
(the box will offer a reasonable default text, depending on
the context in which you use this function. It will either
use the current selection from the code view or the currently
selected method).
If you are only interrested in sends within the current class and
subclasses (i.e. usually in YOUR classes), you can also use the
"local senders"
menu function.
who implements a particular message
- activate the
"implementors
function in the method menu
- fill in selector to search for. You can use wildcards (i.e. a matchpattern).
If you are only interrested in implementations in the current class
and subclasses (i.e. usually in YOUR classes), you also can use the
"local implementors"
menu function.
which method is executed if I sent #foo
Use this search to search up the class inheritance for an implementor
of a particular message.
- activate the
"find method"
function in the method menu
- fill in selector to search for
which methods reference/modify a particular instance variable
- use any of the
"variable search"
submenu functions in the
class list popup menu.
The menu contains entries to search locally in the current class
only ("instvar refs/mods"
, "classvar refs/mods"
)
and
entries which descent down and also search in subclasses
("all instvar refs/mods"
, "all classvar refs/mods"
).
Since searching involves parsing the source code, these functions
may take a while to show the result.
which methods reference a particular global variable
- activate the
"globals"
menu functions in the method list
- enter the name of the global
Notice:
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
- Use the
"classRefs"
function from the class list.
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.
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 interrested in methods with more than 10 arguments, try:
SystemBrowser browseAllSelect:[:cls :method :sel |
sel numArgs > 10
]
or, to find all method 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 these
useful when searching for 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
which can be done automatically if all of them have a distinct category.
("fileOut-all"
function in the method category list).
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 source-files 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 source-file.
If you are working in multiple projects, define some per-project directory
in the project-view. The systemBrowser will save the files into the
active projects directory.
Be careful about overwriting existing sourcefiles when filing out:
since the methods source is typically extracted from some sourcefile,
overwriting one of these will lead to funny results. All fileOut functions
will be changed in upcoming versions to take care about this, but currently
you should not fileOut into the 'source'-directory or one of the 'libXXX'
directories.