You can also use the message **Form new** to create an instance of Form, and then use one of the following messages to initialize its variables:

**extent: aPoint**

Change the receiver width and height to the coordinates of aPoint.

**width: w height: h**

Change the receiver width to w and height to h, and allocate its bitmap with the appropriate size.

**width: w height: h initialByte: aByte**

Change the receiver width to w and height to h, and initialize every byte in the bitmap to aByte.

Other useful messages are **copy:from:to:rule:**, which copies the contents of one Form to another Form; **displayAt:** and **displayOn:at:clippingBox:rule:mask:**, which display the contents of a Form on the screen; and **outputToPrinter**, which shows the contents of a Form on a printer. Refer to the description of Form in Part 4, *The Encyclopedia of Classes*, for the definition of these messages.

## BitBlt

Class **BitBlt** ("bit block transfer") describes all the parameters in a basic bitmapped operation. This basic bitmapped operation is to move a block of bits from one place to another. More complicated operations, such as drawing a line, involve a sequence of such basic moves. This basic operation can sometimes become rather complicated when all the parameters are involved.

This basic operation works as follows. You first define a source rectangle on the source form. The bits from the source rectangle are combined with the bits from the mask form with a logical AND operation. The resulting rectangle of bits are combined into the destination Form rectangle with a specified combination rule and clipping rectangle.

The following figure shows how the parameters of a BitBlt determine which bits are involved in the bit transfer:
<figure><img src="image_58.png" /><figcaption>Figure 14.2
**BitBit** Clipping</figcaption></figure>

And the following figure shows how the resultant bits are produced by combining the source bits, mask bits, and destination bits with a combination rule:

<figure><img src="image_59.png" /><figcaption>Figure 14.3
**BitBit** Operation</figcaption></figure>

For example, suppose

source bits = 11110000

mask bits = 10101010

dest bits = 00001111

rule = logical OR

the resultant bits would be 10101111. These resultant bits are then stored back to the destination Form.
A mask form has a fixed width and height of 16. If its extent is smaller than the source rectangle extent, its bits are repeated both horizontally and vertically up to the extent of the source form rectangle so that they can be ANDed with each bit in the source rectangle. The effect of this is to provide a halftone texture for the 1 bits in the source rectangle. The mask Form, therefore, is also called halftone Form. The following expressions obtain a prebuilt mask Form whose halftone is the same as the message name:

Form white
Form black
Form gray
Form darkGray
Form lightGray

When the destination is a ColorForm or ColorScreen and the source is a Form or BiColorForm, a BiColorForm mask can be used to obtain colors other than black and white. This is not a rare case. For example, both Pen and CharacterScanner instances are in this category. BiColorForm has two additional instance variables: foreColor and backColor. When a BiColorForm is used as a mask form, its foreColor specifies the color for 1 bits and the backColor the color of 0 bits after source bits are ANDed with the mask form bits. To obtain a BiColorForm mask, the following messages can be used:

BiColorForm color: 1.

BiColorForm gray foreColor: 2 backColor: 4.

The first message returns a 16 by 16 BiColorForm whose bitmap consists of all 1 bits and whose foreground color is 1 (blue) and background color is 0. The second message returns a 16 by 16 BiColorForm whose bitmap consists of alternating 0 and 1 bits and whose foreground color is 2 and background color is 4.

When the ANDed source bits are combined into the destination form rectangle, two additional parameters must be specified. One is the *combination rule*, which indicates how the source bits are to be combined with the destination bits. The other is the *clipping rectangle*, which limits the affected area on the destination form. To access the combination rules supported by Smalltalk/V, send a message to class Form:

<table><tr><td>Form over</td><td>destination becomes source</td></tr><tr><td>Form orRule</td><td>source OR into destination</td></tr><tr><td>Form andRule</td><td>source AND into destination</td></tr><tr><td>Form under</td><td>source AND into destination</td></tr><tr><td>Form erase</td><td>if source is 1 then destination becomes 0</td></tr><tr><td>Form reverse</td><td>source XOR into destination</td></tr><tr><td>Form orThru</td><td>first erase without specifying mask Form, then OR with mask Form specified</td></tr></table>

The final affected area on the destination Form can be simulated as follows:
AffectedRect := sourceRect intersect:
                  sourceForm boundingBox.

AffectedRect moveBy: destRect origin - sourceRect origin.

AffectedRect :=
((AffectedRect intersect: destRect)
  intersect: destForm boundingBox)
  intersect: clippingRect

The instance variables of BitBlt are:

sourceForm destForm halftone rule width height

sourceX sourceY destX destY clipX clipY clipWidth clipHeight

Refer to BitBlt in Part 4, The Encyclopedia of Classes for a description of all instance variables.

In terms of instance variables, the source rectangle is defined as:

sourceX @ sourceY extent: width @ height

The destination rectangle is defined as:

destX @ destY extent: width @ height

And the clipping rectangle is defined as:

clipX @ clipY extent: clipWidth @ clipHeight

The sourceForm must be either nil or an instance of Form or its subclasses. The halftone must be either nil or an instance of Form or BiColorForm with width and height equal to 16. The destForm must be an instance of Form or its subclasses. All other instance variables must be a SmallInteger. When sourceForm or halftone is nil, it implies an infinitely large form with contents of all 1 bits.

Note that the source form and destination form can be the same form. In this case, the only complication is that the source rectangle may overlay the destination rectangle. When such overlay occurs, the operation is carried out as if the source bits were first copied to an intermediate Form, and then copied to the destination rectangle. The actual implementation still amounts to a single move and is as efficient as moving between different Forms.

To create an instance of class BitBlt, use the class message:

destForm:sourceForm:

with only destination and source forms specified. Other instance variables are supplied with the following default values:
sourceX := sourceY := 0.

destX := destY := 0.

clipX := clipY := 0.

width := destForm width.

height := destForm height.

clipWidth := destForm width.

clipHeight := destForm height.

rule := Form over

If you want to specify all parameters, use **BitBlt new** to create an instance, and then send the following message to the new instance to set the instance variables:

destForm:

sourceForm:

halftone:

combinationRule:

destOrigin:

sourceOrigin:

extent:

clipRect:

Class **BitBlt** supplies numerous messages to change a small number of parameters. Refer to **BitBlt** in Part 4, The Encyclopedia of Classes for a list of all messages.

After the parameters have been correctly set up, two messages in class **BitBlt** actually move the bits:

copyBits

does exactly what it says: moves bits from one place to another.

drawLoopX: xDelta Y: yDelta

draws a line from the destination origin to:

$(destX @ destY) + (xDelta @ yDelta).$

The line is drawn by performing a sequence of **copyBits**, starting from the destination origin up to the other end of the line. For each **copyBits**, the destination origin is moved by one pixel horizontally and/or vertically towards the other end.
## CharacterScanner

CharacterScanner is a subclass of BitBlt. Its main function is to convert a String of ASCII characters to displayable bitmapped shapes. It therefore adds an instance variable, curFont, which contains the current Font being used for conversion. A Font provides a Form containing all the bitmap images of characters. It also has an index table which gives the source origin of each character within the Form. (Class Font is discussed in Chapter 15.) To display a Character, you use its ASCII value to obtain the source origin from the index table and then move the bitmap image to the destination form.

To create a CharacterScanner, use either the expression:

```
CharacterScanner new
    initialize: clipRect
    font: aFont
```

or

```
CharacterScanner new
    initialize: clipRect
    font: aFont
    dest: aForm
```

The former method uses Display as the destination form, while the latter specifies a Form as its destination. Both specify aFont as the current font and clipRect as the clipping rectangle.

CharacterScanner has an instance variable, frame, which is initialized by both of the above messages to contain clipRect. This allows you to temporarily change the clipping rectangle and later restore it back to frame.

To specify colors, CharacterScanner has another two variables: foreColor specifies the color of the character, and backColor specifies the color of the background. They default to black and white, respectively, with both of the above messages.

To display a string, send the following message to a CharacterScanner:

```
display: aString
    at: startPoint
```

where startPoint is the top left corner, relative to the origin of the frame, of the displayed string. To display a portion of a string, send the message:

```
display: aString
    from: startChar
    to: endChar
    at: startPoint
```
where `startChar` and `endChar` bracket the portion of the string to be displayed. Another message,

* `display: aString from: startChar at: startPoint`

displays `aString` from `startChar` up to its last character at `startPoint` in the frame. In addition, it blanks out the rest of the line after the last character. This is often used when replacing a portion of the line with another string. Blanking out the rest of the line is needed since the length of the line may change after the replacement.

If you want to display a string without bothering its background, use the message:

* `show: aString from: start at: aPoint`

which displays `aString` from `start` character up to its last character at `aPoint` in the frame without changing the background.

Other useful messages are:

* `displayForm: aForm at: aPoint rule: aRule`
  Display `aForm` at `aPoint` in the frame using `aRule`.

* `gray: aRect`
  Color `aRect` in frame with gray tone.

* `reverse: aRect`
  Reverse the color of `aRect` in frame.

* `setFont: aFont`
  Change the font to `aFont`.

* `setterule: aRule backColor: bColor`
  Set the foreground color to `aRule` and background color to `bColor`.

## Pen

Class `Pen` provides a graphics interface similar to turtle graphics. It adds the following parameters to `BitBit`:

* `location` consists of `destX` and `destY`, which represent the integer coordinates of a Pen's current location, and `fractionX` and `fractionY`, which represent the hundredth fractional part of the coordinates.

* `direction` is an instance variable containing a number between 0 and 359 degrees, which specifies where the Pen is heading. 0 makes the Pen go east, 90 makes it go south, and 270 north.
* `downState` is an instance variable containing true or false, indicating whether the Pen draws while it moves.

The source form of a Pen represents its nib. Thus, to draw a thicker line, simply expand the extent of the source form. The mask form provides the color of the Pen. The destination form is the form on which the Pen is going to draw. The clipping rectangle limits the area on which the drawing can have any effect.

The expression:

**Pen new**

creates a Pen with a nib of size 1 by 1, black color, **Display** as its destination form, the entire **Display** area as its clipping rectangle, the center of the **Display** as its **location**, a direction of north, and its `downState` equal to true. The expression:

**Pen new: aForm**

creates a similar Pen except, that it draws on **aForm** rather than **Display**.

The following messages (in addition to the ones provided in BitBlt) can be used to modify a Pen's parameters:

**black**

Change the Pen color to black.

**gray**

Change the Pen color to gray.

**white**

Change the Pen color to white.

**changeNib: aForm**

Change the source Form (nib) to **aForm**.

**defaultNib: shape**

Change the size of the nib to **shape** which can be either a number or a point.

**direction: aNumber**

Set the direction to **aNumber** degrees.

**turn: anInteger**

Turn the receiver Pen **anInteger** number of degrees which can be either positive or negative.

**down**

Set down the pen.
**up**

Lift up the pen.

**home**

Center the pen on the destination form.

**north**

Set the direction to 270 degrees.

**place: aPoint**

Position the receiver Pen at aPoint.

The following messages move the Pen by a certain pattern. If the Pen is down, the pattern will be drawn:

**grid: scale**

Draw a grid within the clipping rectangle where *scale* is the space between lines.

**bounce: increment**

If the Pen touches the clipping rectangle after going for increment, change its direction so that it looks like bouncing off the wall.

**ellipse: r aspect: asp**

Draw an ellipse with pen position as its center, r as half of the width, asp as the ratio of ellipse height to width. The height will be adjusted by Aspect.

**fillAt: aPoint**

Color all pixels that are connected to aPoint and have the same color as that of aPoint by the pattern contained in mask form.

**go: distance**

Move the receiver Pen for length distance in the current direction. The y-axis will be adjusted by Aspect.

**goto: aPoint**

Move the receiver Pen to aPoint.

**polygon: length sides: n**

Draw a polygon with n sides, each length long.

Notice that the **ellipse:aspect:** and **go:** messages both adjust their y-axis by the ratio contained in the global variable **Aspect**. With this adjustment, you can draw a real circle or a real square. To find out the correct **Aspect** ratio for your screen, first display a Form with the same width and height, measure with a ruler the width and height of the displayed rectangle, and evaluate:
**Aspect** := measuredWidth / measuredHeight.

Class Pen has a subclass called **Commander**. An instance of **Commander** contains an Array of Pens. Many messages implemented by **Pen** are reimplemented in **Commander** so that every **Pen** in the **Commander** receives the same message. This creates the illusion that all pens are moving at the same time. To create a **Commander**, evaluate the following expression:

**Commander new: numberOfPens.**

A **Commander** has two unique messages:

**fanOut**

Turn each Pen's direction by an increment of 360 / (number of Pens).

**lineUpFrom: startPoint to: endPoint**

Place all pens on a line specified by `startPoint` and `endPoint` with pens equally spaced between the two points.

## Animation

Class Pen also has another subclass, called **Animation**. Each instance of **Animation** contains an object kept as a Pen with a name, a color, and an Array of pictures. When an object moves, the **Animation** erases its old image before displaying it at the new location. To create an **Animation**, evaluate:

**Animation new initialize: aRectangle**

where *aRectangle* is the clipping rectangle on **Display**. To add an object to an **Animation**, send the message:

**add: formArray name: aName color: aSymbol**

The *formArray* is an Array of Forms simulating the continuous movement of the object. The argument *aName* is normally a String or a Symbol to identify the object. The argument *aSymbol* is the selector for a unary message which can be sent to class **Form** to return a mask form (such as `#black`, `#white`, etc.).

**Animation** has the following messages to change the behavior of its objects:

**tell: name bounce: increment**

Tell the object with the *name* to bounce for *increment* distance.

**tell: name direction: anInteger**

Tell the object with the *name* to change its direction to *anInteger*.

**tell: name go: distance**

Tell the object with the *name* to go for *distance*.
**tell: name place: aPoint**

Tell the object with the name to be placed at aPoint.

**tell: name turn: anInteger**

Tell the object with the name to turn by anInteger degrees.

**speed: anInteger**

Change the distance between the consecutive copies to anInteger. The larger the distance, the faster the object moves.

**shiftRate: anInteger**

Specify how many times the current picture will be copied before shifting to the next one. By increasing the value of anInteger, the motion within the object will appear slower even though it is traveling the same distance.

## Integrating Color and Monochrome Displays

Many applications expect to run on both monochrome and color displays with one Smalltalk/V image. Following are some guidelines for developing such applications.

When you want to create a Form that contains a portion of the display, use the message:

### Display compatibleForm

to obtain the class of the new Form. It returns either class Form or class ColorForm depending on whether the class of Display is DisplayScreen or ColorScreen, respectively. For example:

### Display compatibleForm fromDisplay: (0 @ 0 extent: 100 @ 100)

creates a Form or ColorForm containing the top left 100 by 100 area of the screen without worrying about whether the screen has color or not.

When you want to create a mask that is compatible with the destination, use the message compatibleMask. It returns class Form if the receiver of the message is a Form, BiColorForm, or DisplayScreen; or returns class BiColorForm if the receiver is a ColorForm or ColorScreen. This message is often used in conjunction with the message color: to obtain the desired color. For example:

### Display compatibleMask color: 1

returns either a Form with all 0 bits if Display is a DisplayScreen, or a BiColorForm with all 1 bits and a foreground color 1 if Display is a ColorScreen. The way the color: message works is as follows. If the receiver is class BiColorForm, then the color: message returns a 16 by 16 BiColorForm with all 1 bits and its foreground color set to the argument and background color set to 0. If the receiver is class Form, the message returns a 16 by 16 Form with all bits set to 0 if the argument of the message is between
0 and 7, or set to 1 if the argument is between 8 and 15. In other words, for a Form mask, the color: message maps the first eight colors into 0 bits and the remaining 8 colors into 1 bits. Because of this mapping, when you use a Pen or a CharacterScanner, you had better choose the foreground colors from one set of eight colors and background colors from the other set of eight colors. Otherwise, when you run on a monochrome display, you will end up drawing white on white, or black on black, making the result invisible.

## Multiprocessing Classes

Object-oriented computing in Smalltalk involves communicating objects which send messages to each other to perform useful work. Although this suggests parallel computation, it actually is not. An object always waits to receive a response after sending a message. The situation corresponds to that of using a procedural language, where at any point in time there is a stack of incomplete procedure calls, and there is a single procedure which is active. In Smalltalk, there is a stack of incomplete message sends, and there is a single method which is active.

Smalltalk/V provides parallel processing by defining multiple stacks of incomplete message sends, where each stack is represented by a separate object of class Process. Since there is a single processor, the parallelism is simulated. At any time, only a single process is executing. However there may be many processes ready to execute and there are well defined conditions under which Smalltalk/V switches to a new current process. Semaphore objects are provided for synchronization among processes.

A new process is created by sending the message fork to a block. For example:

[Transcript show: 'Hello'; cr] fork.

Transcript show: 'Goodbye'; cr

This example creates a separate process to execute the code within the block and continues execution of the current process in the code following the block. The result displayed in the System Transcript is:

Hello
Goodbye

The output shows that the new process is initiated before the current process is continued, although both processes operate at the same priority. Processes can be given different priorities by sending the forkAt: message to a block. For example:

[[Transcript show: 'world!'; cr] forkAt: 2.

Transcript show: 'Hello'] forkAt: 3

The example above creates two new processes, one at priority two and the other at priority three. Since higher priority processes are scheduled first, the output on the System Transcript is:
Hello world!

Multiprocessing is especially useful in discrete event simulation because it allows each simulation object to carry out its behavior as a separate process, using semaphores to synchronize processes. Multiprocessing is implemented in Smalltalk/V by classes Process, ProcessScheduler and Semaphore.

For some interesting examples of multiprocessing applications in Smalltalk, see the following publications:

A Little Smalltalk, Timothy Budd, Addison-Wesley 1987, page 116, "The Dining Philosophers Problem".

Smalltalk-80, the Language and its Implementation, Adele Goldberg and David Robson, Addison-Wesley 1983, page 262, "Resource Sharing".

Semaphore

Semaphore is a subclass of Object. A Semaphore is an object used to synchronize multiple processes. A process waits for an event to occur by sending the message wait to a semaphore. A process signals that an event has occurred by sending the message signal to a semaphore.

A semaphore has two instance variables:

signalCount

Contains an Integer representing the number of signal messages minus the number of wait messages sent to the semaphore during its entire lifetime.

waitingProcesses

Contains an OrderedCollection of processes that have sent the message wait to the semaphore without a corresponding signal message. New waiting processes are added at the end of the collection.

An example of the use of semaphores is the following:

| s |

s := Semaphore new.

[Transcript show: '1'] fork.

[Transcript show: '2'.s wait. Transcript show: '3']
forkAt: 3.

[Transcript show: '4'.s signal. Transcript show: '5'; cr]
forkAt: 2.
This example creates three new processes. The output displayed on the System Transcript is:

1 2 4 3 5

This output is created as follows. The fork message creates a process which shows '1'. The forkAt: 3 message creates a process which shows '2' and then is blocked waiting on the semaphore. The forkAt: 2 message creates a process which shows '4' and signals the semaphore. This allows the higher priority process to resume, show '3' and terminate. Then the process at priority 2 resumes, shows '5' and terminates. The initiating process, the user interface, is running concurrently with these processes.

## Process

Process is a subclass of OrderedCollection. A process is a sequence of computations in Smalltalk carried out by objects sending messages to other objects and waiting for the results. An object of class Process describes such a computation sequence. A process has a name and a priority. A process exists in one of several states. Figure 14.4 shows the state transitions a process can make.

<figure><img src="image_60.png" /><figcaption>Figure 14.4 Process State Transitions</figcaption></figure>

The process state transitions occur for the following reasons:

* A new process is created and becomes ready as a result of sending the fork and forkAt: messages to a block.
* A ready process becomes active if it is the longest waiting at its priority and there are no higher priority ready processes and: (1) the active process becomes blocked or dead, (2) the ready process has higher priority than the active process, or (3) the ready process has the same priority as the active process and the following expression is executed:

### Processor yield

* The active process becomes ready when it is replaced by a ready process under the conditions described above for transition 2.

* An active process becomes blocked when the message wait is sent to a semaphore which has no excess signals.

* A blocked process becomes ready when it is the first in the waiting queue of a semaphore and the message signal is sent to the semaphore.

* The active process becomes dead when it reaches the end of the block which caused process creation as a result of the fork or forkAt: messages, or when the following expression is executed:

### Processor schedule

## The User Interface Process

The Smalltalk/V user interface is driven by a single process which responds to all keyboard and mouse input events for all windows. The user interface process alternates between (1) responding to an input event, and (2) waiting for the next input by sending the message wait to global variable KeyboardSemaphore. When there is no input activity, other lower-priority processes can run. The process scheduler guarantees that there is always a lowest priority idle process to run when there is no other system activity.

Errors are handled by a debugger running under the user interface process whether or not the error occurs in the user interface process. If the error: message is sent under the user interface process, the current process is suspended and a new user interface process is created. This allows the process with the error to be debugged with the debugger. If error: is sent by a non-user-interface process, an entry describing the error is placed in the PendingEvents queue (a global variable). PendingEvents is polled for activity by the user interface process when there is no other input activity.

## ProcessScheduler

Class ProcessScheduler is a subclass of Object. A ProcessScheduler controls process execution. There is a single instance of class ProcessScheduler maintained in global variable Processor. The process scheduler determines which ready process is the active process and maintains a queue of ready but inactive processes. The highest priority ready
process is selected as the active process. If there is more than one process at the highest priority, the process that has been ready the longest is chosen.

Process priorities may range between 1 and Processor topPriority.

## Interrupts

Interrupts are the mechanism used for communicating asynchronous external events to Smalltalk/V. Examples of external events are keyboard inputs, mouse movements and clock ticks. The set of interrupt events can be extended by you.

The Smalltalk/V interrupt model corresponds to typical computer hardware interrupt architectures. Interrupts may be explicitly enabled and disabled. When an interrupt event occurs and interrupts are enabled, interrupts are disabled and a vmInterrupt: message is sent to the object at the top of the execution stack for the current process. The argument to vmInterrupt: is the selector of the method defined in Process class which services the interrupt. An interrupt routine concludes by enabling interrupts and returning to vmInterrupt:., which answers self, leaving the execution stack exactly as before the interrupt.

When an interrupt event occurs and interrupts are disabled, the Smalltalk/V places the interrupt event in a pending interrupts queue. Each time interrupts are enabled, the pending interrupts queue is examined to see if there are additional interrupts to be serviced.

The typical interrupt processing method merely signals a semaphore to resume a process to handle the event. For example, the keyboard interrupt handler in class Process is as follows:

* `keyboardInterrupt`
* 'Handle keyboard interrupt.'"
* `KeyboardSemaphore signal`

Note that the semaphore signal message enables interrupts if they are disabled. Interrupts are explicitly enabled and disabled by sending the message `enableInterrupts: to Process` class. Disabling interrupts should be used with extreme caution, because Smalltalk/V cannot respond to external events while interrupts are disabled. The interrupt state may be preserved around a critical code section as follows:

```
| oldState |
oldState := Process enableInterrupts: false. "disable and save state"
    " ... critical code ... "
Process enableInterrupts: oldState "restore interrupt state"
```
Global variable Interrupt Selectors contains an array of selectors corresponding to interrupt events defined as follows:

<table><thead><tr><td>Interrupt Number</td><td>Selector</td><td>Event</td></tr></thead><tbody><tr><td>1</td><td>undefinedInterrupt</td><td>Interrupt number outside array bounds</td></tr><tr><td>2</td><td>controlBreakInterrupt</td><td>Control and break keys struck</td></tr><tr><td>3</td><td>timerInterrupt</td><td>Millisecond clock tick</td></tr><tr><td>4</td><td>ioErrorInterrupt</td><td>DOS critical error</td></tr><tr><td>5</td><td>traceInterrupt</td><td>Debugger hop and skip completion</td></tr><tr><td>6</td><td>breakpointInterrupt</td><td>Debugger breakpoint reached</td></tr><tr><td>7</td><td>lowMemoryInterrupt</td><td>Not much memory left after garbage collect</td></tr><tr><td>8</td><td>keyboardInterrupt</td><td>Mouse events and keyboard inputs</td></tr><tr><td>9</td><td>overrunInterrupt</td><td>Interrupts lost because queue full</td></tr><tr><td>10</td><td>commInterrupt</td><td>Communication port event</td></tr></tbody></table>

Interrupts to Smalltalk/V can be generated from device drivers (see Appendix 2, Primitive Methods). Add the selectors for the new interrupt handling methods to the end of the Interrupt Selectors array.
<figure><img src="image_61.png" /></figure>
# 15 SMALLTALK/V 286 ENVIRONMENT

This chapter describes the Smalltalk/V environment, including

* how to use windows, panes and menus;

* how to use the Smalltalk/V text editor;

* how to evaluate Smalltalk expressions; and

* how to maintain your Smalltalk/V system.

Figure 15.1 shows a typical Smalltalk/V screen with three *windows*. A System Transcript, a Workspace, and a Class Browser.

<figure><img src="image_62.png" /><figcaption>Figure 15.1 Smalltalk/V Screen</figcaption></figure>

Every window in Smalltalk/V has a *label bar* and is surrounded by a *border*. The area inside the border is divided into one or more *panes*. In our example, the Workspace and the System Transcript each have a single pane, and the Class Browser has three panes.

## The Keypad

The arrow that moves around the screen is the *cursor*. You move the cursor by pressing the *cursor arrow* keys on the keypad, as shown in Figure 15.2. Pressing an *arrow key* moves the cursor one space in the direction of the arrow. Pressing the *arrow key* while holding down the *shift key* makes the cursor jump several spaces in the direction of the arrow.

If you have a mouse, the left button serves as the *select key* and the right button for other functions. These keys are described throughout this chapter. You can reassign these keys, and any other keyboard keys if you wish.
<figure><img src="image_63.png" /><figcaption>Figure 15.2
Cursor Movement Keys</figcaption></figure>

If your mouse has three buttons, pressing the middle button produces a beep. You can, however, modify the behavior of the mouse, as well as anything else in the environment. Soon you will feel comfortable enough with Smalltalk/V to customize your system. If you want to program the third mouse button, start with the method **initialState** in class **TerminalStream**. Or, if you find that the scroll speed is too fast or too slow you may want to modify the method **scrollDelay**: in the class **ScrollDispatcher**.

## Active Window

To *select* a window, move the cursor into the window and press the **select** key, or, if you have a mouse, position the cursor within the window and click (quickly press and release) the left mouse button.

The window that you have selected is called the *active window*. The active window is always on top of all other windows and its label bar is reversed. A window remains active regardless of whether or not the cursor is inside it. To deactivate a window, move the cursor outside of the window, and press the **select** key or the left mouse button.

The *screen* is considered the active window if you last pressed the **select** key when the cursor was outside of all windows. When no window is active, all of the label bars have a normal appearance.
# Cycling

Smalltalk/V provides a fast way to move the cursor about the screen. Pressing the **cycle windows** key moves the cursor to the next window in a clockwise direction and automatically activates it. This is called *window cycling*.

Similarly, pressing the **cycle panes** key moves the cursor from pane to pane in a clockwise direction within a window. This is called *pane cycling*.

# Using Menus

## System Menu

Menus are the standard way of giving commands to Smalltalk/V. The *system* menu has commands for creating new windows, saving your work, exiting the environment, and redrawing the screen.

To pop up the system menu, move the cursor outside all windows on the screen, and press either the **window menu** key or the **pane menu** key, or, if you have a mouse, click the right button.

To *select a menu function*, move the cursor to the desired function and press the **select** key (the line on which the cursor sits becomes reversed to show that it is selected). Smalltalk/V immediately performs the action, and the menu disappears.

To *leave a menu* without performing any function, move the cursor outside the menu in any direction. If you have a mouse, then click the left mouse button. The menu disappears.

The other functions of the system menu are described in detail in subsequent chapters.

## Window and Pane Menus

Smalltalk/V includes several menus, some of which are shown in Figure 15.3. You must leave a menu before you can pop up a different menu. The menu that you get at any time is determined by the cursor location and which **menu** key you use.

To pop up a *window menu*, move the cursor into a window and press the **window menu** key or, if you have a mouse, click the right button. If you have a mouse, the cursor must be on the label bar, any border line of the window, or any pane border line within the window. The window menu contains functions specific to that window.
<figure><img src="image_64.png" /><figcaption>Figure 15.3 Smalltalk/V Menus</figcaption></figure>

To pop up a *pane menu*, move the cursor into a pane of the window and press the *pane menu* key or, if you have a mouse, click the right button. The pane menu contains functions specific to that pane.

If you press either menu key or the right mouse button when the cursor is outside of every window, the system menu is popped up.

# Manipulating Windows

## Opening a Workspace

Windows are usually opened from menus. To *open a new workspace*, select *open workspace* from the system menu. An active *workspace* window opens up. This window can be closed, collapsed or resized using the label bar buttons and manipulated like other windows using the *window menu*.

## Label Bar

The label bar, shown in Figure 15.4, displays the window title along with two or more small buttons, depending on which Smalltalk/V window is open. The buttons provide quick access to specific window activities.

To select a button, place the cursor on the button and click the left mouse button or use the numeric keypad + key.

**Close Button:** When selected, the window closes and disappears from the screen.
<figure><img src="image_65.png" /><figcaption>Figure 15.4
Label Bar
and Window
Resizing</figcaption></figure>

**Zoom Button:** When selected, Smalltalk/V zooms in on the text pane so that it fills the whole screen. To unzoom the text pane, click on the label bar and the window redraws to its original configuration. You can also use the F8 function key to zoom a text pane.

**Collapse Button:** When selected, the window collapses to show only the label bar. If the window is already collapsed, selecting this button expands the window to its original size and position on the screen.

**Resize Button:** Select this button and the system responds with a rectangle outline for resizing the window, shown in Figure 15.4.

*With a mouse.* With the cursor on the resize button, press and hold down the left mouse button while you move the mouse to drag the cursor and resize the rectangle outline. Release the mouse button to redraw the window.

*With the keypad.* Select the **resize button** with the numeric keypad + key; then use the keyboard cursor keys to move the cursor and resize the rectangle outline. Press and release the numeric keypad + key to redraw the window.

## Common Window Menu Functions

The window menu of every window has functions that apply to the window as a whole.

To *move a window*, select **move** from the window menu of the window you want to move or move the cursor over the window label and hold down the left mouse button. You'll then see a rectangle outline that is the size of the window being moved. Move the cursor until the rectangle outline is in the desired location and press the **select** key or release the left mouse button. Smalltalk/V moves the window to its new location.
To *frame* or *resize a window*, pop up the window menu and select the *frame* function. *Smalltalk/V* responds with a rectangle outline, as shown in Figure 15.4. Move the rectangle until the lower right corner is in the location you want, and press the *select* key or click the left mouse button. *Smalltalk/V* and changes the window's size.

To change the color of a window, pop up the window menu and select the *color* option. A second menu comes up from which you can choose *text color* or *background color*. Selecting either one causes a third menu containing a palette of 16 colors to appear. Choosing a color makes either the text or background color of the window change accordingly.

**Collapse** causes the window to be collapsed so that only the label bar is visible. The contents of the window remain intact; you just can't see them. To make the contents visible again, select *frame* from the menu and reframe the window or select **collapse** a second time and the window will open to its previous size and position.

**Cycle** causes a window underneath other windows to pop up on top and become the active window. This is the same as pressing the **window cycle** (F9) key.

**Label** lets you type in a new label for the window. When *label* is selected, *Smalltalk/V* pops up a prompter window where you can type a new label. Just type the new label, and press the **return** key when finished.

**Close** causes the window and its contents to disappear.

## Panes

Windows are composed of one or more panes. There are three kinds of panes: *text panes*, *list panes*, and *graph panes*.

Many of the windows in the *Smalltalk/V* environment have panes that allow you to modify or edit text. These are called *text panes*. The System Transcript is a window with only a single text pane, as is any Workspace. These and all other text panes use the same text editor.

Other windows in the *Smalltalk/V* environment have panes that allow you to select from a list of items. These are called *list panes*. Windows that have list panes are usually referred to as *browsers*. The Class Browser is an example of a window with two list panes and one text pane.

The third kind of pane, *graph pane*, allows you to draw pictures. Since *graph panes* are not used by any of the standard windows in the *Smalltalk/V* environment, they are not explained in this chapter. Refer to the graphics and windows tutorials and reference sections for more information.
<figure><img src="image_66.png" /><figcaption>Figure 15.5 Pane with Scroll Bar and Cursor</figcaption></figure>

## Scrolling

There are many instances when the contents of a pane are larger than the pane itself. You can think of a pane as a screen which lets you see only a portion of a pane's contents, as shown in Figure 15.5. Scrolling lets you move this screen around the text so that you can see a different portion of it.

You can scroll through a file using either the mouse or keypad keys. However, when you use the mouse, you have access to the **scroll bar**.

The scroll bar displays the relative location of the visible contents of the file to the file as a whole. By positioning the scroll cursor on the scroll bar and releasing the right mouse button, you *quick jump* around the file.

Experiment with this often missed feature. It is particularly useful for use with large files where scrolling would be time consuming.

## Scrolling With the Keyboard

To *scroll vertically*, use the PgUp and PgDn keys. Pressing PgUp moves the pane contents up one line, while pressing PgDn moves the pane contents down one line.

To *scroll horizontally*, use the Home and End keys. Pressing Home moves the pane contents four characters to the right. Pressing End moves the pane contents four characters to the left.
Holding down the **shift** key when pressing any of the four scrolling keys causes the pane contents to move a larger amount in the indicated direction. For vertical scrolling, the pane contents move almost the entire height of the pane. For horizontal scrolling, the pane contents move one-half of the pane width.

## Scrolling With a Mouse

There are two ways to scroll a pane using a mouse. One way is to grab a character and pull it to the position in the pane where you want it. Continuous scrolling is also available.

In the **grab and pull** technique, the grab location is the position of the cursor when you press the right mouse button. Position the cursor at a character in the last line of a text pane in the active window. Press the right mouse button. Keeping the button down, move the cursor to the first line of the pane and a few characters over to the left. Release the button. If you did not move the cursor out of the pane before you released the button, you will see that the text has been pulled to the location of the cursor when the button was released.

For a *horizontal continuous scroll*, press the right button while the cursor is in the pane you want to scroll. Holding the button down, move the cursor to the right of the pane, then back inside the pane, then move it outside to the left of the pane. Do not allow the cursor to go above or below the pane. Now release the button. While the cursor is back inside the pane, scrolling pauses. When the cursor is moved back out of the pane, scrolling is resumed. When the button is released, scrolling ends.

For a *vertical continuous scroll*, press the right button down while the cursor is in the pane you want to scroll. Holding the button down, move the cursor above the pane or on the top border of the pane. Notice that the pane scrolls down. Similarly, if you move the cursor below the pane or on the bottom border, the pane scrolls up.

Vertical scrolling speed is controlled by the horizontal position of the cursor in relation to the width of the pane. As you move the cursor to the left, the speed slowly decreases until you move the cursor past the left border of the pane. At this point, scrolling speed is at its slowest. As you move the cursor to the right, the speed gradually increases until you move past the right border of the pane. Now scrolling is at its maximum speed, almost a page at a time.

To *pause* during the scroll, move the cursor back into the pane. To *resume* scrolling, move the cursor out of the pane as you did to start the scroll. To *terminate* scrolling, release the button.

To *quick jump* through large chunks of text without scrolling, position the scroll cursor on the scroll bar to locate the section of the file you want to see, and release the right mouse button. The pane will now show the area of the file you located on the scroll bar.
# Text Editor

## Inserting Text

Whenever you press the **select** key, an I-beam is drawn between two characters to mark the *text insertion point*. As you type characters, they appear in front of the text insertion point, which moves to the right with each keystroke. If you press the **backspace** key, the characters in front of the insertion point is deleted, and the insertion point moves a space to the left.

To *move the insertion point*, place the cursor at the new position and press the **select** key. The insertion point jumps to the cursor position.

Whenever the cursor is outside the text editing pane, if you try to type a character, your system beeps, and the character does not appear. You can only edit the contents of a text pane if the cursor is inside the pane.

## Return, Tab, and Backspace Keys

Pressing the **return** key moves the insertion point to the beginning of a new line. If the insertion point was in the middle of a line, the line is split into two lines at the insertion point.

If you press the **tab** key, blanks will be inserted at the insertion point to make it move to the next tab stop. In this editor, tab stops occur every four spaces.

If you press the **backspace** key, the character in front of the insertion point is deleted. Notice that if the insertion point is at the beginning of a line and backspace is pressed, the line is joined to the line above.

## Selecting, Replacing, and Deleting

To *select text*, move the cursor to either the beginning or end of the text to be selected. This position can be at any character, even in the middle of a word. Press the **select** key to bring the insertion point to the cursor. Now move the cursor to the other end of the text to be selected (again, at any character position) and press the **extend selection** key. The entire selected area is reversed. Notice what happens if you move the cursor and press the **extend selection** key again. The selected (reversed) area of text now ends at the new cursor position. You can continue to move the cursor and adjust the selected text by pressing the **extend selection** key until you've selected the text you want as shown in Figure 15.6.
<figure><img src="image_67.png" /><figcaption>Figure 15.6
Selected Text</figcaption></figure>

If you press the **select** key, the selected text is deselected (no longer reversed) and the insertion point appears at the cursor.

Selecting text with a mouse works in a similar fashion.

To *insert* text in a text pane of the active window, position the cursor where you want the insertion point to be, then click the left mouse button. Now the I-beam appears and you can type.

To *select* text in the active window, you can use a method similar to using the **extend selection** key. First move the cursor to the point where you want to begin or end your selection, and click the left button. To extend the selection, move the cursor to the other end of the text then hold down the **shift** key, and press the left mouse button. The text selection will now extend to the current cursor location.

You can also select text using the *draw through* method. Position the cursor at one end of the text you want selected. Now press the left mouse button. Hold the button down as you move the cursor to the other end of the selection. Notice that as you move the cursor, the selection (the reversed text) follows and includes the current cursor location. Draw through terminates when you release the button. Note that if you move the cursor outside the pane while holding the left mouse button down, the pane will scroll while extending the selection.

To *select a single character*, position the cursor at the character you want to select. Then press down the left button and hold it until the character is reversed. This takes only a fraction of a second.

To *select a whole word*, position the cursor anywhere on the word to be selected and double click the left mouse button. The word is reversed.
To *select a line*, place the cursor just inside the window border to the left of the line you wish to select and click the left mouse button twice.

To *replace* text, select the text to replace and then type the new text. As you type, Smalltalk/V replaces the selected text with the new text.

To *delete* large amounts of text, select the text and press the **backspace** key. To delete text one character at a time, place the insertion point at the end of the text to be deleted and press the backspace key.

## Saving and Restoring

The text editor in Smalltalk/V is always working with a text copy of some underlying object in the system. Among other things, this can be a file, a string, or some Smalltalk code. For example, the System Transcript and any Workspace edit strings of characters, and the text pane in the Class Hierarchy Browser edits Smalltalk code. Because a copy is being edited, you must tell the environment when editing is complete. Smalltalk/V can then store the edited text back in the original place. You can also restore the text in the pane to its previous state, if you wish.

Every pane that allows text editing has editing functions on its pane menu.

The *restore* function replaces the text in the pane with the text representation of the underlying object being edited. If you are editing a string, then the string replaces the text in the pane. If you are editing a file, the text in the file is reread into the pane. If you are editing Smalltalk code, then the source code currently being used by the system is put in the pane.

The *save* function in the pane menu tells Smalltalk/V that editing is complete. Smalltalk/V responds by updating the underlying object being edited with the text currently in the pane. For example, if a file is being edited, then the file is rewritten with the text in the pane.

## Cutting, Copying, and Pasting

The text editor has a buffer that can be used to transfer text from place to place. Text is placed in this buffer by either *cutting* or *copying* it from the pane. After text has been placed in the edit buffer, it can be *pasted* anywhere inside of a text pane. This is shown in Figure 15.7.

To place text in the edit buffer you must first select the text. Then, pop up the pane menu and select either *cut* or *copy*. If the *cut* function is selected, Smalltalk/V responds by replacing the contents of the edit buffer with the selected text, and then deleting the selected text from the pane. If the *copy* function is selected, the selected text is not deleted from the pane. Instead a copy of the text replaces the contents of the edit buffer.
<figure><img src="image_68.png" /><figcaption>Figure 15.7
Cutting and Pasting</figcaption></figure>

Text in the edit buffer can be pasted into the pane by either inserting it into a new place or replacing some existing text. To insert the contents of the edit buffer, place the insertion point at the desired position and then select the **paste** function from the pane menu. To replace some text with the contents of the edit buffer, first select the text to be replaced and then select the **paste** function from the pane menu.

The paste function leaves the contents of the edit buffer unchanged. This means that the same text can be pasted several times and in different places.

Since the same edit buffer is shared by all of the text panes, you can easily transfer text between windows. First select the text to be transferred. Next, place this text into the edit buffer by using the pane menu to either cut it or copy it. Then move the cursor into the new window and either place the insertion point where the text is to be inserted or select some existing text that is to be replaced. Now, use the **paste** function from the pane menu. The text appears in the new window.

## Saving the Image

The *image* is all of the Smalltalk objects, both code and data, that make up the Smalltalk/V environment. The image is read from the *image* file when the system starts up. In this way, the objects are loaded into memory. These objects include the windows that appear on the screen.

Since Smalltalk/V is an interactive and modifiable environment, the image is constantly being changed as you use and modify Smalltalk/V. These modifications are not written on the disk until you ask them to be written. This can be done at any time by selecting
the *save image* function from the system menu. You can also save the image while exiting as described below. The next time you start up the system, it resumes exactly as it was when the *image file* was last written.

The *image file* on the disk represents the last saved version; therefore it also becomes the starting point in the event of a system crash or a major mistake. For these reasons, you should maintain a recent backup of the *image file* along with the *source file* and the *change log* that is associated with these files. *Maintaining Smalltalk/V*, later in this chapter, explains the relationships between these files in more detail, and gives instructions on maintaining them. It also gives advice on how to recover from a system crash or other problem.

## Exiting Smalltalk/V

To exit Smalltalk/V, select *exit Smalltalk* from the system menu. You'll then see another menu, asking whether to remember or throw away the changes made since the environment was started.

Selecting the *save image* function causes the state of the system, including the location and contents of all the windows, to be saved. When you start Smalltalk/V the next time, it will be restored to the saved state.

Selecting the *forget image* function causes all of the changes made since Smalltalk/V was started to be forgotten. When Smalltalk/V is started the next time, it will be restored to the previous saved state (the way it was when it was started this time).

Selecting the *continue* function returns you back to the Smalltalk/V environment. This has the same effect as leaving the menu without selecting anything.

## Evaluating Smalltalk Expressions

The Smalltalk language includes expressions which are similar to expressions in other programming languages. In the Smalltalk/V environment, you can enter the text for an expression in any text pane, evaluate it, and display the result. You specify what you want to do in the environment by using pop-up menus and by evaluating Smalltalk expressions, which serve as the Smalltalk/V command language.
## Doing and Showing

All text panes in the system support immediate expression evaluation via their pane menus. To *evaluate an expression*, you must first select it, then pop up the pane menu and select either the *do it* or the *show it* function. If you choose *show it*, the expression is evaluated and a character representation of the expression value is inserted in the pane after the evaluated text. If you choose *do it*, the expression is evaluated and the expression value is thrown away. Notice that only the selected text is evaluated; the other text in the pane is ignored. Extra blanks at the beginning or the end of the selected text are similarly ignored.

Any legal Smalltalk expression or expression series can be selected in a text pane and evaluated. Temporary variables can be declared as needed.

## Compilation Errors

When you select and evaluate an expression, Smalltalk/V compiles and then evaluates it. If it detects a compilation error, Smalltalk/V inserts an error message in the source code at the point of error. To fix the error, simply edit the text in the window, and evaluate the expression again.

## Making Command Templates

You do not need to type the expression that you want to evaluate. You can edit some existing text in the pane and then select and evaluate it. This feature makes it possible to build a window or even a file of useful expressions that you can edit as command templates to construct new expressions for evaluation. File *sample.sml* contains several useful expressions. You can use the Disk Browser to look at and evaluate the expressions contained in this file. These expressions all have comments explaining them.

You can add to the expressions in this file (or make files of expressions of your own) using the Disk Browser. You can include comments with your expressions by merely enclosing the comment in double quotes like this: `"this is a comment"`.

## Prompters

Prompters are a special kind of text editing window that appear on the screen when you request something that requires additional information. The label of a Prompter is a message called a prompt, which tells you what information Smalltalk/V needs to finish the operation. You enter your response into a single text pane of the Prompter. Often a default response appears in the text pane as shown in Figure 15.8.
<figure><img src="image_69.png" /><figcaption>Figure 15.8
Prompter</figcaption></figure>

The text editor used by a Prompter is the same as the text editor described under Text Editor above, except for the following differences:

Smalltalk/V uses Promoters to request a single piece of information from you. You must answer the request or tell Smalltalk/V that you want to cancel whatever operation is requesting the information. Since you must respond to the request, Smalltalk/V will not deactivate the prompter window until you do so. In addition, a Prompter has no window menu. Smalltalk/V will beep if you press the window menu key.

The pane menu of a Prompter (which you pop up by pressing the **pane menu** key) gives you two choices which are specific to Promoters. When you select the *accept* function, the Prompter sends the text in the pane to the requestor of the information. When you select the *cancel* function, the Prompter sends nil to the requestor. The requestor will cancel the operation. Pressing the *return* key is the same as selecting the *accept* function from the pane menu. After the request is answered, either by accepting or canceling, the prompter window disappears.

## The System Dictionary

There is a class in Smalltalk/V known as **SystemDictionary**. There is only one instance of this class, the **System Dictionary**. The System Dictionary defines methods for system-oriented functions such as compressing the **change log** and determining available memory. It also contains all of the names known globally in the system. This includes the names of the classes, global variables, and pool dictionaries. The System Dictionary is referred to in Smalltalk code with the name **Smalltalk** which identifies a global variable. All global variable names must begin with a capital letter. An example of a message to the System Dictionary is the following expression:
## Smalltalk unusedMemory

This computes the number of bytes of available memory in your system.

This chapter describes the System Dictionary and some of the system commands (messages) that are sent to it.

## System Dictionary Contents

The System Dictionary contains all of the names of the classes, global variables and pool dictionaries in the system. In addition, as you define classes, global variables, and pool dictionaries, their names are added to the System Dictionary.

For the classes present in the dictionary, the key is the class name and the value is the class itself. For the global variables present in the dictionary, the key is the variable name and the value is an object. If the variable has been defined but not initialized, its value is nil. Some of the more important global variables present in the system are listed below, along with their values and a brief description. The pool dictionaries are explained in more detail at the end of this chapter.

<table><thead><tr><td>Variable</td><td>Description</td></tr></thead><tbody><tr><td>Aspect</td><td>A Fraction which contains the aspect ratio of your display.</td></tr><tr><td>CharacterConstants</td><td>A pool dictionary. CharacterConstants associate names with special character values such as: carriage return, line feed, escape, form feed, etc.</td></tr><tr><td>CurrentEvent</td><td>An InputEvent used by the environment for reading all keyboard and mouse events.</td></tr><tr><td>CurrentProcess</td><td>The Process that is currently running.</td></tr><tr><td>Cursor</td><td>A CursorManager used to store the location of the cursor.</td></tr><tr><td>Disk</td><td>A Directory. The current directory when the system is booted.</td></tr><tr><td>Display</td><td>A DisplayScreen which is used to access the video screen as a form.</td></tr><tr><td>FunctionKeys</td><td>A pool dictionary. This dictionary defines names for keyboard function key values and for mouse input codes.</td></tr></tbody></table>
<table><thead><tr><td>Variable</td><td>Description</td></tr></thead><tbody><tr><td>KeyboardSemaphore</td><td>A Semaphore that is signaled every time there is a keyboard or mouse interrupt. CurrentEvent waits on this Semaphore.</td></tr><tr><td>Processor</td><td>The ProcessScheduler of the system.</td></tr><tr><td>Scheduler</td><td>A DispatchManager which manages the scheduling of windows. Scheduler should be the only instance of class DispatchManager in the system.</td></tr><tr><td>Smalltalk</td><td>The SystemDictionary.</td></tr><tr><td>Sources</td><td>An Array containing two file streams for accessing the source code of Smalltalk/V. The first entry is the source file. The second entry is the change log file.</td></tr><tr><td>SysFont</td><td>The default Font used for the current graphics resolution.</td></tr><tr><td>Terminal</td><td>A TerminalStream which is used for reading the keyboard and mouse, if any.</td></tr><tr><td>Transcript</td><td>A TextEditor which is the System Transcript. Transcript is used primarily for system messages. The user can also send his messages to it (e.g., for debugging traces).</td></tr></tbody></table>

## System Dictionary Methods

There are many useful functions or methods which operate on the System Dictionary. They include:

<table><thead><tr><td>Method</td><td>Description</td></tr></thead><tbody><tr><td>at: key put: anObject</td><td>Creates a new global variable, key, with the value anObject. If the global variable exists, changes its value to anObject.</td></tr></tbody></table>
<table><thead><tr><td>Method</td><td>Description</td></tr></thead><tbody><tr><td>compressChanges</td><td>Compresses the <strong>change log</strong> file, removing all but the latest version of the methods.</td></tr><tr><td>compressSources</td><td>Compresses the <strong>source</strong> file after updating it with the latest version of the methods in the <strong>change log</strong> file.</td></tr><tr><td>implementorsOf: aSymbol</td><td>Returns a Method Browser containing all of the classes which define a method with the name <em>aSymbol</em>. This is equivalent to choosing the <strong>implementors</strong> function on the method list pane menu of the Class Hierarchy Browser.</td></tr><tr><td>keys</td><td>Returns all of the keys currently defined in the System Dictionary.</td></tr><tr><td>removeKey: key</td><td>Removes the specified key from the System Dictionary.</td></tr><tr><td>sponsorsOf: aSymbol</td><td>Returns a Method Browser containing all of the methods, and their corresponding class names, which send a message with name <em>aSymbol</em>. This is equivalent to choosing the <strong>sponsors</strong> function on the method list pane menu of the Class Hierarchy Browser.</td></tr><tr><td>unusedMemory</td><td>Returns the number of bytes free in the system.</td></tr></tbody></table>

## Pool Dictionaries

A dictionary contained in a global variable can be used as a pool dictionary.

### CharacterConstants

CharacterConstants is a pool dictionary associating names to special ASCII character values such as line feed and escape. The keys of this dictionary are descriptive strings and the values are the associated ASCII characters as shown below:

<table><thead><tr><td>Key String</td><td>ASCII Character</td></tr></thead><tbody><tr><td>Bell</td><td>Bell character (ASCII value 7)</td></tr><tr><td>Bs</td><td>Back space character (ASCII value 8)</td></tr></tbody></table>
<table><thead><tr><td>Key String</td><td>ASCII Character</td></tr></thead><tbody><tr><td>Cr</td><td>Carriage return (ASCII value 13)</td></tr><tr><td>Del</td><td>Delete character (ASCII value 127)</td></tr><tr><td>Esc</td><td>Escape character (ASCII value 27)</td></tr><tr><td>Ff</td><td>Form feed character (ASCII value 12)</td></tr><tr><td>FunctionPrefix</td><td>First character of a function key two character sequence (ASCII value 0)</td></tr><tr><td>Lf</td><td>Line feed character (ASCII value 10)</td></tr><tr><td>MouseButton</td><td>Character sent when any mouse button changes state (ASCII value 254)</td></tr><tr><td>SetLoc</td><td>Character sent when the mouse moves (ASCII value 255)</td></tr><tr><td>Space</td><td>Space character (ASCII value 32)</td></tr><tr><td>Tab</td><td>Horizontal tab character (ASCII value 9)</td></tr><tr><td>UpperToLower</td><td>SmallInteger of value 32, the numeric difference between upper and lower-case ASCII value characters</td></tr></tbody></table>

## FunctionKeys

FunctionKeys is a pool dictionary associating names to the function key values such as cursor movement keys and menu keys. By assigning a new value to a function key name, a different key on the key board can be associated to the named function.

## Maintaining Smalltalk/V

In this section, the procedures for maintaining the system are discussed. These include:

* How to keep the files that the system uses from getting too big.

* Some simple steps that you can take to protect yourself from losing all your work in the event of a total failure (crash) of the system.

* What to do if the system does crash.
## Automatic Logging of Changes

As you define and modify classes or methods, Smalltalk/V is logging all of these changes to the **change log**. Smalltalk/V maintains pointers from the compiled methods in the environment to the latest version of the source code. If the source code has never been changed, the pointer goes to the **source file**. Otherwise, the pointer goes to the **change log**. As a result, the disk is accessed as you browse the methods in a class. Furthermore, since the **image file** contains pointers to the **source file** and the **change log**, you must maintain these three files as a group.

For these reasons, you must not edit or modify the change log! You can view it with the Disk Browser and you can reinstall methods and class definitions from it into your system. This capability can be used to facilitate recovery from a system crash and is explained in more detail in the section on Surviving a System Crash in this chapter.

Other important events are automatically logged by Smalltalk/V. Every time the image is saved, a message with the date and time is written to the **change log**. Every Smalltalk expression that you evaluate with either *do it* or *show it* is also logged. In addition, every time you remove a method from a class, a message is logged.

The format of the **change log** is very similar to the one described by Glenn Krasner in Chapter 3 of *Smalltalk-80: Bits of History and Words of Advice*, Addison-Wesley, 1983. A brief description of this format using the EBNF notation described in *Appendix 1* follows.
`<rule> changeLog = {textChunk}`.

`<rule> textChunk = sourceCode | classDefinition | expression | imageComment.`

`<rule> sourceCode = '!' classname ' methods ' { method '!' } ' !'.`

`<rule> classDefinition = ' 'define class' ' classDefinitionMessage '!'.`

`<rule> expression = ' 'evaluate' ' evaluatedText '!'.`

`<rule> imageComment = ' '*** saved image on: ' dateAndTime '****' !'.`

where: classname is
the name of a class.

method is
a valid method as defined in Part 2 of this manual with occurrences
of "!" replaced by "!!".

classDefinitionMessage is
a valid class definition message to the class's superclass as defined
in Part 2 of this manual.

evaluatedText is
the text evaluated by *do it* or *show it* with all occurrences of "!"
replaced by "!!".

dateAndTime is
the character representation of the date and time the image was
saved.

The change log is an ASCII text file which means that you can print it at any time. A
simple examination of the file should remove any questions regarding its format.

## Importance of Saving the Image

Smalltalk/V is written entirely in Smalltalk. The image that is referred to in this manual is the collection of all Smalltalk objects that make up the environment.

When you save an image, descriptions of all of these objects are written out on the image file. When you start the system at a later time, all of the objects described in the image file are recreated exactly as they were at the time the image was saved. Since these objects contain everything that makes up the Smalltalk/V environment, the system starts up exactly as you saved it.

As you use the system by writing Smalltalk code or using the environment for other
purposes, new objects are created and existing objects have their contents changed. You
must save the image to make your changes permanent. You can save the image by either
selecting the *save image* function from the system menu or by selecting the *save image* function as you are exiting the environment. If you do not save the image, the environment will not have any of your changes the next time it is started.

If you forget to save the image, you can recover these changes. Items that were logged in the *change log* are still present, and you can install them again using the Disk Browser (see Surviving a System Crash later in this chapter). Not saving the image is useful when you are developing something new and you decide that you have made a major mistake that you would like to discard.

## Compressing the Change Log

Compressing the *change log* reduces it to only the latest copy of each new or changed method. Class definitions are removed. A new *image file* is written automatically.

You should compress the *change log* when it starts to get large. There must be enough space on the disk for both the new and the old *change log* at the same time, so make sure you compress the *change log* before the disk gets too full.

To *compress the change log*, evaluate the following expression in any text pane (the System Transcript for example):

### Smalltalk compressChanges

If there is not enough room on the disk, delete some files and then try it again.

## Compressing the Source File

Compressing the *source file* creates a new *source file* for all of the methods currently in the system by taking the latest copy of the source code for each method from the old *source file* or *change log*. A new *image file* and an empty *change log* are automatically written.

The *source file* is written in a compressed format to preserve space on the disk. There are pointers from the compiled methods in the image to the *source file* and to the *change log*. For these reasons, it is *imperative* that the *source file* not be edited or altered except by *Smalltalk/V*. Copying the source is okay. You should always use the same *image file* with the same *source file* (or a *copy* of it) and the same *change log*.

After you compress the sources, you will have a new *image file* and a new *source file*. The *change log* will be empty. Therefore, you should make backup copies of the *source file*, the *change log file*, and the *image file* before compressing the sources so if anything goes wrong, you can recover.
To compress the sources, evaluate the following expression in any text pane (the System Transcript, for example):

### Smalltalk compressSources

After compressing the sources, you have a new base system. You should make a backup copy of the new *source*, *image*, and *change log* files. Maintaining backup copies will allow you to recover from most, if not all, problems that might occur.

Retaining your old change logs gives you a record of all the changes you have made to the system. This will prove invaluable when you receive a new release of Smalltalk/V.

## Surviving a System Crash

Smalltalk/V is very resilient to errors. Unfortunately, disasters can and will happen, especially if you are making modifications to Smalltalk/V. The automatic logging feature of Smalltalk/V makes it possible to recover from most disasters. Disasters happen not because Smalltalk/V has bugs in it, but because it is a modifiable program development environment. Smalltalk/V will let you change anything, even if it destroys the environment.

For example, if you make a mistake changing the method for the walkback window, or if the hardware fails, you may see the error message: `doesNotUnderstand: is missing`. This means that Smalltalk/V cannot find the code that displays the appropriate walkback message and has terminated.

This presents no problem since you can recover most, if not all, of your work very quickly. In fact, experimenting with the system is a good way to learn about it, but make sure you take the following precautions:

1. Always have a backup copy of the *source file* that you are currently using. Smalltalk/V never modifies the *source file* and neither should you. When you compress the sources, as explained in *Compressing the Source File*, a new *source file* is made. Make a backup copy of it immediately.

2. Always have a reliable backup copy of the *image file* and *change log file*. Remember that the *image* and the *change log* work together. If you use an *image file* with an older version of the *change log*, you may not be able to access the source code for some methods. After you compress the changes (see *Compressing the Change Log*), the *image* and *change log* files are both replaced. You cannot use an old *image file* with a new compressed *change log file*. You can use an old *image* with a later version of the same *change log* if the *change log* has not been compressed between the time when the *image* was made and when you use the *change log*. In short, back up the *image* and *change log* together, and you shouldn't have any problems.
3. You should save the **image** onto the disk (you can do this from the system menu) before trying something that might crash the system. Doing so will preserve most of your work. If the system crashes, you can restart Smalltalk/V using this saved image. If you fail to save the **image** and the system crashes, you can use the Disk Browser to examine the **change log**.

4. If you have been experimenting with Smalltalk/V and you have any reason to believe you have damaged the system or if there are changes you do not want to make permanent, **do not save the image**. Exit the Smalltalk/V environment using the **forget image** function. Remember, most of the changes you have made are in the **change log** and they can be reinstalled selectively.

5. If Smalltalk/V crashes, don't panic. Make a copy of your **image** and **change.log** file. Usually, you can recover your work, and if you make a copy, you can try repeatedly. Read the next section for information on how to recover.

## Recovering From a System Crash

If the system crashes you should make a copy of your **image** and **change.log** file before proceeding. To recover your work, follow these steps:

1. Check if you have a good **image** file. To find out, try to start Smalltalk/V in the usual way using this file. If it does not start up, then you should get your most recent backup of the **image** and **change log** and start Smalltalk/V with that version.

2. Now that you have Smalltalk/V running, use the Disk Browser to look at the **change.log** file that you were using when the system crashed. The **change log** has all of the modifications that you made and all of the expressions that you evaluated.

3. Find the point in the **change log** where you saved the **image** that you are currently running. Every time that the **image** is saved, Smalltalk/V writes a comment into the **change log** giving the time and date when the **image** was saved. Scan the **change log** backwards, if you were using a recently saved **image**.

4. Now that you have found the point at which you saved the **image**, you know that your lost work is from this point to the end of the **change log**. Remember that the **change log** is formatted as a series of chunks. The exact format is given in the section Automatic Logging of Changes in this chapter. To restore your work, select one or more consecutive chunks of text. You must select complete chunks—watch the exclamation points (!). Next,
pop up the *pane* menu and select the *install* function. If a chunk is an expression, it will be evaluated. If a chunk is a method definition, it will be recompiled and installed into the system. Choose the chunks that you install carefully—one of them represents the error, and you don't want to put it back into the system.

When you have finished recovering what you want, save the image.

## Purging Unused Symbols

Unused symbols tend to accumulate slowly over time in Smalltalk/V because instances of class *Symbol* are not collected as garbage. Evaluate the following expression to remove all symbols that are no longer referenced.

### Smalltalk purgeUnusedSymbols

The number of symbols recovered and the amount of space reclaimed is usually quite small.

## Cloning

Cloning is a process which builds a new *image* file from the current image. The Cloner does a complete memory walk of all of the objects in Smalltalk/V. Cloning does not in and of itself reclaim any space or objects. The image file is fully compacted every time the image is saved. Cloning does not remove unused symbols. Cloning the system is a good way of verifying that all of the objects in the image are undamaged.

The Cloner can also be used to build a version of the system that has many of the classes removed. In order to specify these classes and objects, you must edit the method `initializeClones` in file `cloner`.

Note that when you clone, the *image* file will be re-written. Therefore, you should back up your *image* file before cloning.

The Cloner classes are not resident in Smalltalk/V. To clone Smalltalk/V, an expression must be evaluated to read and execute a file. The file installs several classes into Smalltalk/V and then uses them to clone the system. The cloned system does not contain the cloning classes.

If the file `cloner` is in your disk directory, (the same directory as the *image* file), then evaluate the following expression in any *text* pane, (e.g. the System Transcript):

*(Disk file: 'cloner.st') fileIn.*

When cloning is finished, Smalltalk/V will exit to DOS. You should make a backup of your *image* file.
# DOS Shell

The DOS Shell capability allows you to quickly exit Smalltalk/V to execute DOS commands and programs, and then return to Smalltalk/V when finished. For example, you could use this capability to format a floppy disk or to run a word processing program, and then return to Smalltalk/V.

Choosing dos shell from the system menu pops up another menu with several choices of single DOS commands you can execute. In addition, a to dos choice exits you to the DOS command processor COMMAND.COM from which you can run several DOS commands and programs. To resume Smalltalk/V use the DOS EXIT command.

## Reserving Space for DOS

In order to use this feature you must reserve space for DOS when starting up Smalltalk/V. The memory you reserve is not used by Smalltalk/V. You specify the amount of space to reserve for DOS as the argument to the /d: parameter on the command line that invokes Smalltalk/V. For example, the following command invokes Smalltalk/V and reserves 200K for DOS to use.

v /d:200

Notice that the argument is a decimal number and specifies the amount of memory to reserve in multiples of 1024 bytes. Appendix 3, Configuring Smalltalk/V 286, explains all of the command line options in detail.

## How It Works

The method executeCommands: in class ScreenDispatcher does all of the work. For example, this expression displays text on the display screen using the DOS echo command:

Scheduler systemDispatcher
executeCommands: #('ECHO hello from Smalltalk/V' 'PAUSE')

The argument is a collection of strings containing the DOS commands to execute, in this case an array with two strings containing the echo command and the pause command. These strings are written to the file smaltalk.bat, along with a few DOS commands to return to the appropriate directory so Smalltalk/V can resume properly. Smalltalk/V runs the DOS commands by executing this batch file.

As a final example, here is the method executed in ScreenDispatcher when you select go to DOS from the DOS menu; it exits to the DOS command processor COMMAND.COM:
gotoDOS

"Exit to COMMAND.COM"

self executeCommands:

#('ECHO OFF

'ECHO TO resume Smalltalk/V, enter EXIT'

'CD \'

'COMMAND.COM')

Font and Cursor Shapes

Font

Smalltalk/V represents characters in strings using their ASCII codes. In order to display them on the screen or printer in bitmapped graphics mode, these ASCII values must be converted into bitmap images. Class CharacterScanner (refer to Chapter 14) performs the conversion while instances of class Font provide the character bitmap image needed for conversion, and information about how to retrieve the image.

Smalltalk/V includes two fonts. This section provides you with the information about
how to install your own fonts.

The expression Font eightLine returns a Font whose characters have a size of 8 by 8 pixels, while the expression Font fourteenLine returns a Font with characters of 8 by 14 pixels.

The following global variables govern the fonts used by different parts of the system:

<table><thead><tr><td>Global Variable</td><td>Used by</td></tr></thead><tbody><tr><td>LabelFont</td><td>window labels</td></tr><tr><td>ListFont</td><td>ListPane</td></tr><tr><td>TextFont</td><td>TextPane</td></tr><tr><td>SysFont</td><td>all others</td></tr></tbody></table>

You can change the first three global variables to contain different fonts; when you open new windows, you'll see the new fonts being used. To change the SysFont to aFont, use the expression

Font setSysFont: aFont.

The instance variables of Font are the following:

charSize

Contains a Point representing the width and height of each character.
**glyphs**

Contains a Form of bitmap images of all characters. The images are attached horizontally. For example, if the font contains 100 characters and charSize is 8 by 14, then its glyphs Form will have a width of 800 (100 * 8) and height of 14. Each Font can contain a maximum number of 256 characters.

**xTable**

Contains an Array of the x coordinate of the origin of each character image in the **glyphs** Form. It contains one entry more than the number of characters contained in the Font.

**startChar, endChar**

Contain the ASCII value of the first and last character, respectively, in the Font. There cannot be any missing values between `startChar` and `endChar`. For characters with an ASCII value outside of the range `startChar` to `endChar`, the glyph for `endChar` is used.

**basePoint**

Contains a Point whose x value is always 0 and whose y value indicates the base line of the font.

To install a fixed width new font, evaluate the following expression:

**Font new**

```
installFixedSize: glyphForm
charSize: sizePoint
startChar: x
endChar: y
basePoint: bPoint
```

This initializes all the instance variables and automatically creates the `xTable`.

**Cursor Shapes**

Smalltalk/V uses different cursor shapes to visually indicate system status. For example, the hourglass cursor shape is used to indicate a computation is in progress. Cursor shapes are also a good way to convey status information about your applications.

Smalltalk/V supports the Microsoft Mouse and its compatibles (e.g. PC Mouse, Logitech Mouse). It therefore has two interfaces to deal with cursors. When you have a mouse, the cursor is managed by class **CursorManager**. When you do not have a mouse, it is managed by class **NoMouseCursor**. **CursorManager** merely provides an interface between Smalltalk/V and the mouse driver supplied by the mouse manufacturer. **NoMouseCursor**, on the other hand, handles with Smalltalk code everything related to
the cursor. Smalltalk/V automatically detects whether or not there is a mouse and sets a global variable, **Cursor**, to be an instance of the appropriate class. The user interface to **Cursor** is identical for either class.

Normally when you display something that covers the cursor, you should first hide the cursor; otherwise, cursor writing by the mouse driver may interfere. To simplify this problem, all system primitives that can alter the contents of the screen currently make sure that the cursor is hidden before the altering, and restored after.

For the advanced user, the expression **Cursor hide** hides the cursor and **Cursor display** displays it. These two messages work like parentheses: they must be balanced. For example, suppose the cursor is currently being shown; if you hide it twice and then display it once, you must still display it again to show it. If you are not sure which level the cursor is at, and it is not displayed, evaluate the following expression:

### Cursor reset

This forces a balance of hide and display and shows the cursor.

To change the cursor shape, simply send the message **change** to the cursor instance to which you want to change. For example:

### CursorManager execute change

changes the cursor shape to an hour glass (indicated by **execute**). Smalltalk/V includes 11 prebuilt cursor shapes:

<table><thead><tr><td>Message to CursorManager</td><td>Shape</td></tr></thead><tbody><tr><td>normal</td><td>an arrow pointing north west</td></tr><tr><td>execute</td><td>an hour glass</td></tr><tr><td>origin</td><td>an angle bracket pointing north west</td></tr><tr><td>corner</td><td>an angle bracket pointing south east</td></tr><tr><td>downArrow</td><td>an arrow pointing down</td></tr><tr><td>upArrow</td><td>an arrow pointing up</td></tr><tr><td>leftArrow</td><td>an arrow pointing left</td></tr><tr><td>rightArrow</td><td>an arrow pointing right</td></tr><tr><td>crossHair</td><td>a cross</td></tr><tr><td>hand</td><td>a hand</td></tr><tr><td>scroll</td><td>four arrows pointing out from the center</td></tr></tbody></table>

To temporarily see a cursor shape on the screen, use the same expression followed by a **Terminal read**. For example:
CursorManager hand change. Terminal read

displays the hand cursor, and then returns to normal when you type anything.

Creating a cursor of your own is equally simple. First create a cursor form using the **BitEditor** included with **Smalltalk/V**. (The cursor form must have an extent of 16 @ 16.) Then evaluate the following expression:

NewCursor :=
    CursorManager new
    initialize: cursorForm hotSpot: aPoint

The argument **cursorForm** is the Form containing the cursor image. The hot spot **aPoint** is the point of the image that will be aligned with the actual cursor position. To make the new cursor the active cursor, evaluate:

NewCursor change
# 16 SMALLTALK/V 286 STANDARD WINDOWS

This section describes the special windows which Smalltalk/V provides for maintenance and debugging purposes.

The *Disk Browser* displays the files on a given directory, and their contents. It also lets you edit those contents.

The *Class Hierarchy Browser* shows you the interrelationship of the classes within Smalltalk/V, and lets you edit the code for each class.

*Inspectors* let you examine and edit objects. They serve as a low-level debugging aid.

*Walkback* and *Debugger* give views of the state of your program at the point of an error. They are high-level debugging aids.

*Method Browsers* let you browse and edit a list of methods.

Browsers use indexes to access information. Often the information is organized in a hierarchical manner. A browser is a window consisting of at least two panes, a *list* pane and a *text* pane. Selecting from the list displays related information in the text pane. This text may be modified, and eventually saved.

## Disk Browser

The Disk Browser lets you browse the files on a disk device. To open a Disk Browser, select *browse disk* on the system menu. Smalltalk/V responds with a menu of available disk devices. Select the drive whose directory you want to see. Smalltalk/V then opens the new Disk Browser. You can have as many Disk Browsers open at a time as you want.

The Disk Browser is divided into four panes, as shown in Figure 16.1.

The *directory hierarchy* list appears in the upper-left pane. In this pane, the names of all the directories on the disk are listed. You will see a backslash symbol (\) in the top corner of the pane. This symbol stands for the root or parent dictionary of the entire disk. The names of the directories in the parent directory are indented and appear in hierarchical order. Initially only the first level of subdirectories are displayed and an ellipsis (...) is used to indicate that there may be subdirectories. By selecting *hide/show* from the pane menu or double-clicking on a directory name, the full subdirectory hierarchy will be shown.

The *file* list is in the pane to the right of the directory hierarchy list. When a directory is selected in the directory hierarchy list pane, its files will appear in this pane.

The *contents* pane shows the text of a selected file or further directory information if no file has been selected.
<figure><img src="image_70.png" /><figcaption>Figure 16.1
Disk Browser</figcaption></figure>

The *directory order* pane contains a statement telling you how the information in a directory is ordered when it is displayed in the contents pane. The pane menu associated with the directory order pane gives you the choice of ordering the directory by date, name, or size.

The label bar of the Disk Browser displays other useful information. If the disk being browsed is labeled, the label is displayed between the brackets, [ and ]. The full path name of the currently selected directory in the browser is displayed. If no directory is selected, then only the device drive character appears. The numbers at the right side of the label represent the amount of free space on the disk. This number is automatically updated as you use the browser.

## Browsing Directories

To *select a directory* to browse, move the cursor into the directory list pane and press the *select* key when the cursor is on top of the directory you wish to browse. Smalltalk/V displays a list of file names in the file list pane (the right-hand pane) and a complete listing of the directory information in the contents pane (the bottom pane). You can move the cursor or scroll the directory list pane and select a different directory any time you wish.

The directory hierarchy list pane menu has four selections:

*Remove* eliminates a subdirectory from the disk. You will get an error if there are files in the subdirectory

*Update* allows you to browse another disk in the same drive. Selecting this function tells the window to update itself by rereading the directory structure on the disk. You should select this function only after you have inserted the second disk.
Hide/Show expands the subdirectory hierarchy if the selected directory has an ellipsis (...) at the end, or hides the subdirectories if they are displayed. Note that the same effect can be achieved by merely clicking on a selected directory name.

Create makes a new directory as a subdirectory of the selected directory. When you select this function, a prompter appears, asking for the path (directory) name.

## Browsing Files

To select a file to browse, move the cursor on top of the file name in the file list pane and press the **select** key. Smalltalk/V responds by displaying the file contents in the contents pane. You can select another file to browse by selecting it in the file list pane.

The menu for the file list pane displays a variety of functions for files. The file list pane is the top-right pane of the Disk Browser.

Remove eliminates the selected file and its contents.

Print causes the selected file to be printed.

Mode permits you to change the system file mode bits (see your PC or MS-DOS manual) of the selected file.

Rename lets you change a selected file's name.

Copy duplicates a selected file in another location.

Create generates an empty new file.

## Editing Contents

Figure 16.2 shows the three menus for the file contents pane, the pane at the bottom of the window. Which menu appears is dependent upon what you select in the other panes.

If you are looking at a directory, you can pop up the menu shown at center. The menu at left can be brought up only if part of a large file has been read into the pane. You can pop up the menu on the right if you have selected a smaller file. All of these menus are popped up by pressing the **pane menu** key (Smalltalk/V knows which one to use) or the right mouse button.

As you can see, the three menus share some common functions. The *copy*, *cut*, and *paste* functions are the same as those used in normal text editing (described in Chapter 15). In addition, the *do it* and *show it* functions are identical to those previously described for Smalltalk expression evaluation. *Save* and *restore* have been explained under text editing as well.
<figure><img src="image_71.png" /><figcaption>Figure 16.2
File Contents
Pane Menus</figcaption></figure>

The *save as* function allows the directory information to be written on a file. You can also edit the information in the contents pane (for example, adding file comments) before writing it on the file.

The other functions of the file contents pane menus are the following:

**Read it** is used to read the entire contents of a large file. Normally, when the text of a file exceeds 10,000 bytes, the pane will only display the first 2,000 bytes, followed by the final 8,000 bytes. Any editing changes performed before *read it* is selected are lost. After you select this function, the entire file is read into the pane. The pane menu will change to the one for small files (one on the right). Now you can perform the save functions.

**Save as** is used to save edited material in a file different from the selected one (*save* rewrites the selected file with the text in the pane). Selecting this function causes a Prompter to appear which asks for the file name. You must respond with the name of a new or existing file.

**Install** compiles the selected text into the system. The selected text must be in the same format as the text in the **change log** or text in a **class definition file**. It is used to evaluate Smalltalk expressions and to compile and install Smalltalk source code from files. Typically, these would be from the **change log** or from a file containing a class definition. This use of the **change log** is described in more detail in Chapter 15. Remember that the code you want to install must be in **change log** format.

## Viewing Directory Contents

The directory order pane is located immediately below the directory list pane. It allows you to see the full information associated with each file in a directory, as well as to control the order in which this information is displayed.
To *display the directory* in the contents pane, move the cursor into the directory order pane and press the *select* key. Smalltalk/V responds by displaying in the contents pane information about the files in the currently selected directory (the one selected in the directory list pane).

The directory order pane menu contains selections to determine how to sort the directory listing. To display the files in the directory in a different order, pop up the pane menu of the directory order pane by pressing the *pane menu* key. You now have a choice of ordering by date, name, or size. After you choose, Smalltalk/V will reorder the files.

## Class Hierarchy Browser

The Class Hierarchy Browser lets you examine the interrelationships of the classes within Smalltalk/V, and to edit their contents.

### Opening a Class Hierarchy Browser

Select the *browse classes* function of the *system* menu to open a Class Hierarchy Browser.

The Class Hierarchy Browser is divided into five panes as shown in Figure 16.3.

<figure><img src="image_72.png" /><figcaption>Figure 16.3
Class Hierarchy
Browser</figcaption></figure>

The *class hierarchy list* appears in the upper-left pane. In this pane, the names of all of the classes in the system are presented in a hierarchical order. Notice that *Object* appears first in the list. *Class Object* is uppermost in the hierarchy. All other classes are subclasses to *Object* and therefore appear indented. Subclasses of these classes are indented further.
The *method list* pane is the pane to the right of the class hierarchy list. In this pane, either a list of the *instance methods* or a list of the *class methods* is presented. The two small panes underneath the method list pane are used to select the desired list. You can choose one by moving the cursor over either the class pane or the instance pane and then pressing the *select key* or the left mouse button. There is no pane menu associated with the class or instance pane. If you press the *pane menu key*, Smalltalk/V will pop up the same menu that the *window menu key* pops up.

The Smalltalk code itself is seen in the *contents pane* which occupies the bottom half of the window. When you select a class in the hierarchy pane, the message which defines the class selected is displayed in this pane. Select a method and its code appears. The *contents pane* is a text pane so it can be edited.

## Browsing the Hierarchy

To *select a class to browse*, move the cursor into the class hierarchy list pane, the top-left pane of the window, and select a class by pressing the *select key*. Smalltalk/V displays the class definition in the *contents pane* and a list of methods implemented by the class in the methods list pane. You can scroll the class hierarchy list pane, like all list panes, with the vertical scrolling keys, *Pg Up* and *Pg Down*, or the mouse.

The class hierarchy list pane menu contains functions which permit you to write the definition of a class and all of its methods on a file, browse a particular class, add a subclass and remove a class.

**File out** writes the class definition along with all of the instance and class messages of the selected class to a file. The file is in a special *change log format* (see *Automatic Logging of Changes* in Chapter 15 for more information). Smalltalk/V derives the file name from the class name with the extension `.cls` and places it in the directory from which Smalltalk/V was invoked. Subclasses are not automatically filed out. The *file out* function does not affect the class in the system.

**Update** tells the *Class Hierarchy Browser* to recompute the class hierarchy list. You must do this if you have removed a class or added a class using another browser.

**Hide/Show** lets you hide or show the subclasses of the selected class. It is useful for shortening the list of classes by hiding the ones not currently of interest. If the subclasses of a class are hidden, an ellipsis (...) appears after the class name. Note that the same effect can be achieved by simply double-clicking on the desired class.

**Add subclass** permits you to add a subclass to the selected class.

**Remove class** lets you remove the selected class.
## Adding Classes

To add a subclass of a class, first select in the hierarchy list pane the class that will be the superclass of the new class. Now pop up the pane menu and select the add subclass function. A prompter with the selected class name in the label then asks for a subclass name.

When you reply to the prompter, a menu then appears asking you what type of subclass you want. The subclass type depends upon whether the objects belonging to the class are to contain named instance variables, indexed instance variables, or byte arrays. After you make a choice, the new subclass is built and the class hierarchy list is automatically updated. This subclass is already selected in order to allow you to define its instance and class variables, add methods to it, or define subclasses of it.

## Defining Classes

To define the instance variables, class variables, and pool dictionaries of a class, you must first select the class in the class hierarchy list pane. Smalltalk/V responds by displaying the current class definition in the contents pane. The definition includes the class's superclass, instance variables, class variables, and pool dictionaries. You change the class definition by editing the text in the contents pane and then selecting the save function from the contents pane menu.

When you change a class definition, Smalltalk/V automatically recompiles all of the methods in the class and all of its subclasses. In addition, a message is written on the system change log giving the new class definition.

Changes to a class definition take effect immediately so that all future instances of the class will have the new structure. You should therefore be very careful when modifying classes that are used by the Smalltalk/V environment because you are changing the environment. Until you are confident with these procedures, you should define subclasses as opposed to modifying the structure of existing classes.

## Removing Classes

To remove a class, first select in the hierarchy list pane the class to be removed. Now pop up the pane menu and select remove class. The system will prompt you for confirmation.

All of the methods in the class are automatically removed when the class is removed. Smalltalk/V will not let you remove a class if it has subclasses or if there are instances of the class anywhere in the environment. If either of these exists, you will get a walkback window explaining the problem. Remember that Smalltalk automatically removes
(collects as garbage) any object that is not referred to by some other object in the system. To remove all instances of a class, you must change all references to instances of the class to refer to something else.

You can send the message **allReferences** to an object to find out all objects that refer to the receiver object.

## Browsing the Methods

The method list pane is the top-right pane of the window. Remember that there are two kinds of methods in a class, **instance methods** and **class methods**. The list that appears is determined by the two panes directly beneath the method list pane, the class and the instance panes. You select the list by moving the cursor over the class or instance pane and then pressing the **select** key or the right mouse button.

To *select a method*, move the cursor into the methods list pane and press the **select** key when the cursor is on top of the desired message selector you wish to select. *Smalltalk/V* responds by placing the source code for the method that implements the message in the contents pane below. You can move the cursor or scroll the methods list pane and then select a different method by pressing the **select** key or the right mouse button.

The method list pane menu contains four functions:

To *remove a method* from the selected class, select the method, pop up the method list menu, and select the **remove** function. The method list is immediately updated.

To *add a new method*, you can use the **new method** function. A template that you can edit appears. You can also edit the text of any existing method in the class. The name of the new method is taken from the first line of the text. In either case, you use the **save** function to invoke the compiler and install the new method. Remember that there are two kinds of methods—class and instance methods. The kind of method you get is determined by whether you have currently selected the class or instance pane.

If a compilation error is detected, you will see a message in your source in the pane at the point where the error was detected. The error message is selected (reversed). Edit the text and use the **save** function again to recompile.

When the method is successfully compiled with no errors, *Smalltalk/V* installs it into the class automatically and all future invocations of this method use this new version. The source code of the new or modified method is written onto the **change log file**.

Senders causes *Smalltalk/V* to search all of the methods in the environment for senders (callers) of the selected message selector. A senders window, which is a kind of Method Browser, pops up to display each method (and its class) that sends a message with the selected message selector.
Implementors causes Smalltalk/V to search all of the classes in the environment for implementors (definers) of the selected message selector. An *implementors* window, which is a kind of Method Browser, pops up to display the names of all the classes that implement methods for the selected message selector.

## Modifying the Source Code for a Method

To see the source code of a different method, move the cursor into the methods list pane and select another message selector. The contents pane is a text pane used for modifying and adding methods.

All of the functions on the contents pane menu behave exactly as described under Text Editor in Chapter 15.

To *modify* an existing method, you must first select it in the method list pane. The source currently being used by the system is displayed in the contents pane. Edit the source code in this pane. After editing the source text, you then use the *save* function on the contents pane menu to invoke the compiler and install the new method in the environment.

## Class Browser

A Class Browser can be opened in either of two ways. You can send the message *edit* to any class or you can select the *browse* function from the *hierarchy pane* menu of the Class Hierarchy Browser described previously in this chapter.

Move the cursor into any text pane. Type in the name of the class you want to browse followed by *edit* and select it. Select the *do it* function from the *pane menu*. Smalltalk/V then opens a Class Browser for the class.

Figure 16.4 shows a Class Browser for the class DemoClass. Class Browsers have three panes: the *dictionary list pane*, the *method list pane*, and the *contents pane*.

The label of a Class Browser identifies the class you are browsing. In this window, only the methods for the selected class can be browsed, added, or modified.

The *dictionary list pane* is the top-left pane that contains the two choices: *class* and *instance*. If you select *instance*, then the list of instance methods is displayed in the *method list pane* immediately below this pane. If you select *class*, then the list of class methods is displayed in the *method list pane*. There is no pane menu associated with the *dictionary list pane*. If you press the *pane menu key*, Smalltalk/V will pop up the same menu that the *window menu key* pops up.
<figure><img src="image_73.png" /><figcaption>Figure 16.4
Class Browser</figcaption></figure>

The method list pane is immediately below the dictionary list pane. It displays the list of **class** or **instance** methods implemented by the class depending on what you choose (class or instance) in the dictionary list pane. This pane lets you choose a particular method implementation for viewing.

The contents pane is the large pane to the right of the two list panes. It displays the currently selected method in the method list pane. You can edit and recompile methods in this text pane.

## Browsing Method Lists

The method list pane displays a list of the message selectors for either the **class** methods or the **instance** methods defined in the class. The choice you make in the dictionary list pane (immediately above this pane) determines which list you see.

The functions on the methods list pane menu let you remove methods and display the implementors (definers) and the senders (callers) of messages. Note that this is very similar to the method list pane described for the Class Hierarchy Browser. The items appearing in both menus function in the same manner. See **Browsing the Methods** for the Class Hierarchy Browser in this chapter for a description of how to select a method and for explanations of the menu functions.

## Modifying and Adding Methods

The contents pane is a text pane used to modify and add methods to the class being browsed. All of these functions behave exactly as described under **Text Editor**.
The process of adding and modifying methods is the same as described for the Class Hierarchy Browser. The Class Browser, however, uses a dictionary list pane while the Class Hierarchy Browser has a class pane and an instance pane.

## The Inspector

Figure 16.5 shows an *inspector window*. Inspectors are used to examine and change objects in the system. They are a low-level debugging aid.

<figure><img src="image_74.png" /><figcaption>Figure 16.5 Inspector Window</figcaption></figure>

To open an *Inspector*, send the message *inspect* to any object. For example, to open an *inspector* on the global variable *Demo*, evaluate the following text:

### Demo inspect.

Inspectors have two panes. The list pane on the left is the *instance variable list pane*. The pane on the right is the *instance variable contents pane*.

The instance variable list pane shows all of the instance variables of the object being inspected. The first item in the list is always the name *self*, which is the object being inspected. The named instance variables, if any, are listed next. If the object being inspected has indexed instance variables, then they are listed last with numerical indices.

When you select one of the variables from the list, its current value is displayed in the instance variable contents pane. If you select *self*, the current value of the inspected object is displayed.

The pane menu of the list pane has only one function, *inspect*. When you select this function, a new *Inspector* is opened on the currently selected instance variable. Also, if you click on a selected item, an *Inspector* window is opened on that item.
The instance variable contents pane is a text pane. The pane menu has the normal text pane functions on it. You can use this pane to evaluate any type of expression that you wish. There are two very important features of this pane:

1. Any expression that you evaluate is compiled in the scope of the object being inspected. This means that you can use the names of all of the instance variables in your expressions.

2. If you select the *save* function from the pane menu, the entire contents of the text pane will be compiled and evaluated. The result of this expression will replace the current value of the selected instance variable in the list pane to the left. Similarly, if you select the *restore* function, Smalltalk/V places the current value of the selected instance variable into this text pane.

## Inspecting Dictionaries

A *Dictionary* is an object which contains associations between keys and values. The Inspector created for objects which are dictionaries are special. The Dictionary Inspector has two panes: an *instance variable list* pane and an *instance variable contents* pane, just like regular Inspectors. Dictionary Inspectors, however, list the keys in the dictionary in the instance variable list pane, rather than instance variable names and indices. When you choose a key in the pane, the associated value is displayed in the instance variable contents pane. Notice that *self* is not on the list pane of a dictionary inspector.

The dictionary inspector pane menu has three selections. Notice that there are two functions not present on a normal inspector's pane menu.

*Remove* allows you to remove the association for a selected key from the *Dictionary*.

*Inspect* opens an *Inspector* on the value associated with the currently selected key.

*Add* allows you to add a new element to the dictionary. The system pops up a *Prompter* asking for the new key. The associated value is nil until you select the new key, change the nil value in the contents pane, and save it.

## Debugger Windows

There are two debugger windows: a *walkback* window and a *debug* window. A *walkback* window pops up automatically when errors are detected. When you need more information than provided in the *walkback* window, you explicitly request a *debug* window using the *walkback window* menu.
## Walkback Window

You request a walkback window by sending the `error:` message to any object with a string describing the error as argument. For example,

`self error: 'Index is outside of collection bounds'`

Smalltalk/V also places a walkback window on the screen when any of the following occur.

* The message `halt` is sent to any object, for example:

`self halt`

* The `break` key is typed at the same time that the control key is pressed, causing a **control-break** interrupt.

* The message-send nesting gets too deep, resulting in a stack overflow condition.

Figure 16.6 shows a walkback window produced by evaluating the expression in the System Transcript. This expression attempts to access the eighth character in the string 'hello', an obvious error.

<figure><img src="image_75.png" /><figcaption>Figure 16.6 Walkback Window</figcaption></figure>

The label of the window describes the error. The text pane of the window contains a **method walkback** showing the incomplete message sends that led to the error. Each line in the text pane represents a single message send, with the most recent send listed first. On each line, the class of the receiver is given first. If the method used is defined in a superclass of the receiver, the class in which the method is defined appears next in parentheses. The string on the right following `>>` is the message selector.
Sometimes you will see lines of the form:

[] in classname >> methodname

This indicates that an error occurred during the evaluation of a block in the method
methodName of the class classname.

Whenever you get a walkback window, you generally do one of three things:

1. You can determine what the problem is from the information contained in the walkback window. In this case, you normally close the walkback window and then go fix the problem.

2. You can resume execution at the point of interruption, provided that the walkback window occurred either as a result of a **control-break** interrupt, or because a **halt** message was sent. In these cases, there is nothing wrong with the program, so you can pop up the pane menu for the walkback window and select **resume**. The walkback window closes and execution continues.

3. You can decide that you need more information, and would like to use the *debugger* to obtain it. In this case, you pop up the pane menu for the walkback window and select **debug**. The walkback window closes and you are prompted for the corners of the debugger window:

## Debugger Window

The debugger window gives you an expanded view of the walkback and allows controlled execution of a process. The window has six panes. Figure 16.7 shows a debugger window.

<figure><img src="image_76.png" /><figcaption>Figure 16.7 Debugger Window</figcaption></figure>
The top left list pane serves two purposes: presenting a walkback and listing breakpoints. If the pane labeled **walkback** is selected, the pane above has the same walkback list that appears in a walkback window. When you select a walkback line, the other panes contain related information.

If the pane labeled **breakpoints** is selected, the pane above lists the class name and method selector for all methods which have breakpoints set. When you select a breakpoint line, the pane below displays the source code for the selected method. Setting a breakpoint in a method causes execution to stop when the method is entered, provided that execution is under control of the debugger (see the description of the **hop**, **skip** and **jump** buttons below).

The bottom pane displays the source code for the selected method and, if **walkback** is selected, the source code for the currently executing statement is highlighted. This pane also serves as a text editor so you can change the code as you do with the Class Hierarchy Browser. You update a method by selecting the **save** entry on the pane menu. If a selected walkback method is updated in this way, all walkback entries above the bottom-most occurrence of the method in the walkback list are discarded, because a method they would return to has changed.

The two panes on the top right serve as an inspector for the receiver, arguments and temporary variables of the selected method. The variable name pane on the left of the two contains **self**, representing the receiver, and the names of all arguments and temporary variables. The variable pane on the right displays the value of the selected variable.

The menu of the variable name pane contains a single entry: **inspect** which allows you to spawn another inspector on the selected object. For example, you can inspect the instance variables of the receiver by double-clicking on **self**.

The menu of the variable value pane is a standard text editing menu. When you select **save**, the value of the selected variable is changed to contain the results of evaluating the expression in the value pane.

The label bar of the debugger window contains three buttons related to debugging: **hop**, **skip** and **jump**. These work as follows:

* **hop** - executes the next expression in the debugged process.

* **skip** - executes the next expression in the selected method or up to the next breakpoint, whichever comes first. Note that **skip** may execute several expressions in lower-level methods.

* **jump** - executes up to the next breakpoint.

The menu of the walkback list pane contains the entries **resume**, **restart**, **senders**, **implementors**, **add breakpoint** and **remove breakpoint**, defined as follows:
* **resume** - as in the walkback window, allows you to continue execution after a halt message or a control-break interrupt. The debugger window disappears and execution continues from the point of interruption. You will not be allowed to resume, however, if you have changed a method in the walkback list.

* **restart** - if a method is selected, the debugger window disappears and execution is restarted by re-sending the message in the selected walkback entry.

* **senders** - as in the Class Hierarchy Browser, a Method Browser window is popped up listing all methods in Smalltalk/V which send the message corresponding to the selected method.

* **implementors** - as in the Class Hierarchy Browser, a Method Browser window is popped up listing all methods in Smalltalk/V which implement a method with the same name as the selected method.

* **add breakpoint** - two prompter windows appear, requesting the class and selector of the method to add to the breakpoint list.

* **remove breakpoint** - the selected breakpoint entry is removed from the breakpoint list.

## Method Browser

The Method Browser lets you browse and edit a list of methods. There are two ways to open a Method Browser. Selecting **senders** in any of the list pane menus (e.g., the method list pane menu of the Class Hierarchy Browser) will open a Method Browser on the list of all methods in the system that send the selected message selector. Selecting **implementors** in any of the list pane menus will open a Method Browser on the list of all methods that implement the selected message selector. These two windows are often referred to as the **senders** window and the **implementors** window respectively. Figure 16.8 shows a Method Browser on all senders of the message **open**.

Method Browsers have two panes. The list pane on the top is the *method list* pane. the pane on the bottom is the *text* pane.

The method list pane shows a list of methods identified by the class and message selector. When you select a method in the list, the source code for the method is displayed in the text pane. The pane menu of the list pane has two functions:

* **senders** causes Smalltalk/V to search all of the methods in the environment for methods that send (call) the selected message selector. A new Method Browser is opened on the methods found.

* **implementors** causes Smalltalk/V to search all of the methods in the environment for methods that implement (define) the selected message selector. A new Method Browser is opened on the methods found.
<figure><img src="image_77.png" /><figcaption>Figure 16.8
Method Browser</figcaption></figure>

The text pane lets you view and edit the source code for a selected method. This pane has the normal text pane editing menu. When you save the edited text, the method is recompiled.
Part 4

Encyclopedia
of Classes
# Animation

An Animation contains a collection of pens representing objects being animated. Each pen is moved by erasing its image from the old location and then displaying the image in a new location. The message interface is similar to class Pen except that a name must be given to identify the object to move. Each pen in the collection behaves differently than a non-animation pen, for example, the instance variable sourceForm of each pen contains an Array of Forms representing pictures in successive stages of a motion. These pictures are displayed in a cyclical fashion for each BitBlt copy. The overlapped objects are displayed in the order as they are entered into the Animation object. Thus an object entered first will appear to always move behind the object entered later.

**Inhabits From:** Pen BitBlt Object

**Inherited By:** (None)

## Named Instance Variables:

### backForm

Contains a Form which is a copy of the background of the animation. A region of this form is pasted onto the underForm to carry out the erasing operation.

### clipHeight

(From class BitBlt)

### clipWidth

(From class BitBlt)

### clipX

(From class BitBlt)

### clipY

(From class BitBlt)

### curPen

Contains a Pen which is one of the animated objects that is currently moving.

### destForm

(From class BitBlt)

### destX

(From class BitBlt)

### destY

(From class BitBlt)

### direction

(From class Pen)

### downState

(From class Pen)

### fractionX

(From class Pen)

### fractionY

(From class Pen)

### halftone

(From class BitBlt)
**height**

(From class BitBlt)

**hideBlt**

Contains a BitBlt which is used to erase the old image.

**pens**

Contains an OrderedCollection of pens with information about each animated object.

**rule**

(From class BitBlt)

**shiftRate**

Contains an Integer specifying the number of times the same picture will be used before shifting to the next picture of an animated object. For example, a spinning ball will appear to be spinning more slowly when its shiftRate is larger.

**sourceForm**

(From class BitBlt)

**sourceX**

(From class BitBlt)

**sourceY**

(From class BitBlt)

**speed**

Contains an Integer specifying the number of pixels to skip between successive moves. Skipping a larger number of pixels gives the illusion of moving at a higher speed.

**underForm**

Contains a Form used as an intermediate place for merging the erasing rectangle and the new displaying rectangle so that the blinking effect is reduced.

**width**

(From class BitBlt)

Class Variables:

**DoubleCenter**

(From class Pen)

Pool Dictionaries: (None)

Class Methods: (None)

Instance Methods:

**add: anArray name: aName color: aColor**

Add the forms in anArray to the receiver with the name aName and color aColor (integer from 0 to 15, or a halftone symbol).

**display**

Display the currently moving object and all the objects it overlaps with.

**initialize: aRectangle**

Initialize the receiver to do animation within aRectangle.
**setBackground**

Set the background form to the contents of the display screen.

**shiftRate: anInteger**

Specify how many times the current picture will be copied before shifting to the next one.

**speed: anInteger**

Change the distance between consecutive copies to anInteger.

**tell: aName bounce: anInteger**

Tell the pen with the name aName to bounce by a distance of anInteger.

**tell: aName direction: anInteger**

Tell the pen with the name aName to change its direction to anInteger number of degrees.

**tell: aName go: anInteger**

Tell the pen with the name aName to go for a distance of anInteger.

**tell: name goto: aPoint**

Tell the object with name to go to aPoint.

**tell: aName place: aPoint**

Tell the pen with the name aName to be placed at aPoint.

**tell: aName turn: anInteger**

Tell the pen with the name aName to turn by anInteger number of degrees.

## Array

An Array is a collection of any objects accessed through a fixed range of integer indices (representing the positions of the elements within the Array). Most of the protocol to handle arrays is inherited from its superclasses. The only methods contained in this class are the methods to print and store an Array on a stream.

Inhabits From: FixedSizeCollection IndexedCollection Collection Object

Inherited By: CompiledMethod

This class contains indexed instance variables.

Named Instance Variables: (None)

Class Variables:

(None)

Pool Dictionaries: (None)

Class Methods: (None)
### Instance Methods:

**printOn: aStream**

Append the ASCII representation of the receiver to aStream.

**storeOn: aStream**

Append the ASCII representation of the receiver to aStream from which the receiver can be reinstantiated.

## Association

Class Association provides the means of associating two objects known as the key/value pair, and defines the protocol to manipulate them. Association objects are often used as the elements of class Dictionary.

**Inhabits From:** Magnitude Object

**Inherited By:** (None)

**Named Instance Variables:**

**key**

Contains the first object of the key/value pair. It is primarily used as a key to retrieve the second object (the value) of the association when dealing with instances of class Dictionary.

**value**

Contains the second object of the key/value pair.

**Class Variables:**

(None)

**Pool Dictionaries:** (None)

**Class Methods:**

**key: anObject**

Answer an instance of class Association whose key is initialized to anObject.

**key: aKey value: anObject**

Answer an instance of class Association whose key is initialized to aKey and whose value is initialized to anObject.

### Instance Methods:

**< anAssociation**

Answer true if the receiver key is less than anAssociation key, else answer false.

**< = anAssociation**

Answer true if the receiver key is less than or equal to anAssociation key, else answer false.
**= anAssociation**

Answer true if the receiver key is equal to anAssociation key, else answer false.

**> anAssociation**

Answer true if the receiver key is greater than anAssociation key, else answer false.

**> = anAssociation**

Answer true if the receiver key is greater than or equal to anAssociation key, else answer false.

**hash**

Answer the integer hash value for the key of the receiver.

**key**

Answer the key of the receiver.

**key: anObject**

Set the key of the receiver to be anObject. Answer the receiver.

**printOn: aStream**

Append the ASCII representation of the receiver to aStream.

**storeOn: aStream**

Append the ASCII representation of the receiver to aStream from which the receiver can be reinstantiated.

**value**

Answer the value of the receiver.

**value: anObject**

Set the value of the receiver to be anObject. Answer the receiver.

## Bag

A Bag is a collection of unordered elements in which duplicates are allowed. It cannot be accessed through external keys. Bags are useful for containing arbitrary objects and for counting occurrences of equal objects. Bags are hashed for rapid searching.

**Inhabits From:** Collection Object

**Inherited By:** (None)

**Named Instance Variables:**

**elements**

Contains a Dictionary. For each key/value pair, the key contains an element of the bag and the associated value represents the number of occurrences of the element in the bag.

**Class Variables:**

(None)
**Pool Dictionaries:** (None)

**Class Methods:**

**new**
Answer an empty Bag.

**Instance Methods:**

**add:** anObject
Answer anObject. Add anObject to the elements of the receiver.

**add:** anObject withOccurrences: anInteger
Answer anObject. Add anObject to the elements of the receiver anInteger number of times.

**at:** anInteger
Answer the element of the receiver at index position anInteger. Report an error since bags are not indexable.

**at:** anInteger put: anObject
Replace the element of the receiver at index position anInteger with anObject. Report an error, since bags are not indexable.

**do:** aBlock
For each element in the receiver, evaluate aBlock with that element as the argument.

**includes:** anObject
Answer true if the receiver contains an element equal to anObject, else answer false.

**occurrencesOf:** anObject
Answer the number of elements of the receiver equal to anObject.

**remove:** anObject ifAbsent: aBlock
Answer anObject. Remove one occurrence of anObject from the receiver collection. If anObject is not an element of the receiver, evaluate aBlock (with no arguments).

**size**
Answer the number of elements in the receiver collection.

## Behavior

Class Behavior is the abstract class that defines and implements the common protocol for all the classes and metaclasses in Smalltalk. Behavior provides methods that support source code access, compilation, object creation, and class hierarchy access.

**Inhabits From:** Object

**Inherited By:** Class MetaClass
## Named Instance Variables:

**comment**

This is reserved for future use.

**dictionaryArray**

Contains an Array of method dictionaries, in message lookup order.

**instances**

Contains an Array of instance variable names defined by this class. The names are stored as strings.

**name**

Contains the Symbol that is the name of this class.

**structure**

Contains a SmallInteger that describes the physical structure of instances of this class. See the class variables of Behavior for the definition of the encoding.

**subclasses**

Contains an Array of all the subclasses of this class.

**superClass**

Contains the superclass of this class.

## Class Variables:

**InstIndexedBit**

Contains a SmallInteger which, when logically ANDed with the instance variable structure, determines whether or not an instance of the class can have indexed instance variables. The value contained is 8192.

**InstNumberMask**

Contains a SmallInteger which, when logically ANDed with the instance variable structure, determines the number of named instance variables for each instance of the class. The value contained is 127.

**InstPointerBit**

Contains a SmallInteger which, when logically ANDed with the instance variable structure, determines whether or not an instance of the class contains object pointers in their instance variables. The value contained is 16384.

**Pool Dictionaries:** (None)

**Class Methods:** (All private)

## Instance Methods:

**addSelector: aSymbol withMethod: aCompiledMethod**

Add aCompiledMethod to the receiver messageDictionary using aSymbol as the key. If aSymbol is not a Symbol report an error.

**addSubclass: aClass**

Add aClass to the subclasses of the receiver. Make the receiver the superclass of aClass.

**allClasses**

Answer a Set of all of the classes contained in Smalltalk.
**allClassVarNames**

Answer a Set of strings of all of the class variable names defined in the receiver and its superclasses.

**allInstances**

Answer an Array of all of the instances of the receiver.

**allInstVarNames**

Answer an Array of strings of all of the instance variable names defined in the receiver and its superclasses.

**allSubclasses**

Answer an OrderedCollection of all the subclasses of the receiver in hierarchical order. Classes at the same hierarchical level are sorted alphabetically.

**allSuperclasses**

Answer an OrderedCollection of all the superclasses of the receiver. The superclasses are in inverse hierarchical order, i.e class Object is last.

**canUnderstand: aSymbol**

Answer true if the receiver or any of the receiver superclasses implement the method named aSymbol, else answer false.

**classVariableString**

Answer a String of all the class variable names defined by the receiver. The names are separated with blanks.

**compile: codeString**

Compile the Smalltalk method contained in codeString. The class to use for resolving variables is the receiver. If there are no errors, add the method to the receiver messageDictionary and answer the Association with the message selector as the key and the compiled method as the value. If there is an error, answer nil.

**compile: codeString notifying: requestor**

Compile the Smalltalk method contained in codeString. The class to use for resolving variables is the receiver. If there are no errors, add the method to the receiver messageDictionary and answer the Association with the message selector as the key and the compiled method as the value. If there is an error the requestor is sent a message by the compiler identifying the error and this method answers nil.

**compiledMethodAt: aSymbol**

Answer the compiled code of the method named aSymbol defined in the receiver.

**compileLogic: codeString**

Compile the Prolog method contained in codeString. The class to use for resolving variables is the receiver. If there are no errors, add the method to the receiver messageDictionary and answer the Association with the message selector as the key and the compiled method as the value. If there is an error, answer nil.

**compileLogic: codeString notifying: requestor**

Compile the Prolog method contained in codeString.
**deepCopy**

Answer a copy of the receiver with shallow copies of each instance variable. Because classes are unique (cannot be copied), answer the receiver.

**implementorsOf**: aSymbol

Answer a collection of methods of myself and my subclasses that implement aSymbol.

**includesSelector**: aSymbol

Answer true if the message dictionary of the receiver includes a method of name aSymbol, else answer false.

**inheritsFrom**: aClass

Answer true if receiver can inherit methods from aClass, else answer false.

**instanceVariableString**

Answer a String containing all the instance variable names defined by the receiver. The names are separated with spaces.

**instSize**

Answer the number of named instance variables contained in instances of the receiver.

**instVarNames**

Answer the array of instance variable names defined by the receiver.

**isBits**

Answer true if instances of the receiver contain 8 bit values instead of object pointers, else answer false.

**isBytes**

Answer true if instances of the receiver contain 8 bit byte values, else answer false.

**isFixed**

Answer true if instances of the receiver do not contain indexed instance variables, else answer false.

**isPointers**

Answer true if instances of the receiver contain object pointers instead of 8 bit values, else answer false.

**isVariable**

Answer true if instances of the receiver contain indexed instance variables, else answer false.

**methodDictionary**

Answer the dictionary of methods defined in the receiver.

**methods**

Answer an instance of ClassReader initialized for the receiver.

**new**

Answer an instance of the receiver. If the receiver is indexable, then allocate zero indexed instance variables. This method is frequently reimplemented as a class message in classes that need special initialization of their instances.
**new:** anInteger

Answer an instance of the receiver. Allocate anInteger number of indexed instance variables. If the receiver does not have indexed instance variables an error is reported. This method is frequently reimplemented as a class message in classes that need special initialization of their instances.

**printOn:** aStream

Print the name of the receiver on aStream.

**removeSelector:** aSymbol

Remove the method named aSymbol from the methods defined in the receiver.

** selectors **

Answer a Set of symbols of the names of the methods defined by the receiver.

**sendersOf:** aSymbol

Answer a collection of methods of myself and my subclasses that send aSymbol.

**shallowCopy**

Answer a copy of the receiver which shares the receiver instance variables. Because classes are unique (cannot be copied), answer the receiver.

**sourceCodeAt:** aSymbol

Answer a String of the source code for the method named aSymbol in the receiver.

** structure **

Answer the integer that describes the structure of instances of the receiver. Refer to the class variables of Behavior for a definition of this integer.

** subclasses**

Answer an Array of subclasses of the receiver.

**superclass**

Answer the superclass of the receiver.

**withAllSubclasses**

Answer an OrderedCollection of the receiver and all of its subclasses in hierarchical order.

BiColorForm

A BiColorForm is like a Form except that it contains two additional instance variables, foreColor and backColor. This enables the BiColorForm to take on two arbitrary colors rather than just black and white. The foreColor is associated with 1 bits and the backColor with 0 bits in the bitmap.

Inhabits From: Form DisplayMedium DisplayObject Object

Inherited By: (None)
## Named Instance Variables:

**backColor**

Contains an integer representing the background color (for 0 bits in bitmap).

**bits**

(From class Form)

**byteWidth**

(From class Form)

**deviceType**

(From class Form)

**foreColor**

Contains an integer representing the foreground color (for 1 bits in bitmap).

**height**

(From class Form)

**offset**

(From class Form)

**width**

(From class Form)

## Class Variables:

**BlackMask**

(From class Form)

**DarkGrayMask**

(From class Form)

**GrayMask**

(From class Form)

**LightGrayMask**

(From class Form)

**PrinterMode**

(From class Form)

**WhiteMask**

(From class Form)

Pool Dictionaries: (None)

## Class Methods:

**black**

Answer a black mask form.

**color**: aColor

Answer a mask form with aColor as the foreground color and black as the background color.

**darkGray**

Answer a dark gray mask form.

**foreColor**: aColor **backColor**: bColor

Answer a mask form with foreground aColor and background bColor.
**gray**

Answer a gray mask form.

**lightGray**

Answer a light gray mask form.

**new**

Answer a new BiColorForm.

**white**

Answer a white mask form.

Instance Methods:

**backColor**

Answer the background color.

**backColor: aColor**

Set receiver's background color to aColor.

**foreColor**

Answer the foreground color.

**foreColor: aColor**

Set receiver's foreground color to aColor.

**foreColor: aColor backColor: bColor**

Set receiver's foreground color to aColor and background color to bColor.

**fromDisplay: aRectangle**

Copy aRectangle area of the display screen to receiver. Screen bits that are the receiver foreground color become 1, the rest become 0.

BitBit

This class defines all the basic graphics operations. Its main function is to transfer bits from one area to another. This involves three forms: the source form, destination form, and mask form. The bits in the source form are first ANDed with the bits in the mask form ( tiled if size is smaller than the source rectangle), and then merged into the destination form with a combination rule. The combination rule specifies a logical operation ( e.g. AND, OR, XOR, etc.) as to how to combine a masked source bit with its corresponding destination bit. The areas involved in this bit transfer are specified by a source rectangle on the source form, a destination rectangle on the destination form, and a clipping rectangle also on the destination form. After alligning the source rectangle origin with the destination rectangle origin, the final affected area is the intersection of all three rectangles. The prebuilt mask forms and supported combination rules can be obtained by sending class messages to Form or BiColorForm (if colors other than black and white are desired).

Inherits From: Object

Inherited By: Animation CharacterScanner Commander Pen
### Named Instance Variables:

**clipHeight**

Contains the height of the clipping rectangle.

**clipWidth**

Contains the width of the clipping rectangle.

**clipX**

Contains the x coordinate of the clipping rectangle origin.

**clipY**

Contains the y coordinate of the clipping rectangle origin.

**destForm**

Contains the destination form for bit transfers.

**destX**

Contains the x coordinate of the destination rectangle origin.

**destY**

Contains the y coordinate of the destination rectangle origin.

**halftone**

Contains the mask form which provides the graytone effect.

**height**

Contains the height of the source (and destination) rectangle.

**rule**

Contains an integer denoting the combination rule.

**sourceForm**

Contains the source form for bit transfers.

**sourceX**

Contains the x coordinate of the source rectangle origin.

**sourceY**

Contains the y coordinate of the source rectangle origin.

**width**

Contains the width of the source (and destination rectangle).

### Class Variables:

*(None)*

### Pool Dictionaries: (None)

### Class Methods:

**destForm: dForm sourceForm: sForm**

Answer a BitBlt with dForm and sForm as its destination and source Forms.

### Instance Methods:

**clipRect**

Answer the clipping rectangle of the receiver.

**clipRect: aRectangle**

Set the clipping rectangle of the receiver to aRectangle.
**clipX**

Answer the x coordinate of the clip rectangle.

**clipY**

Answer the y coordinate of the clip rectangle.

**combinationRule**: anInteger

Set the rule for combining the bits of the source and destination forms to anInteger.

**copyBits**

Copy the bits from the source to the destination form. Hide the cursor if it is within the area of the transfer.

**destForm**

Answer the destination form of the receiver.

**destForm**: aForm

Set the destination form of the receiver to aForm.

**destForm**: dForm **sourceForm**: sForm

Answer the receiver with dForm and sForm as its destination and source Forms.

**destForm**: destination

**sourceForm**: source **halftone**: mask **combinationRule**: combinationRule

**destOrigin**: destOrigin **sourceOrigin**: sourceOrigin **extent**: extent

**clipRect**: clipRect

Initialize all the instance variables of the receiver.

**destOrigin**: aPoint

Set the origin of the destination rectangle to aPoint.

**destRect**: aRectangle

Set the destination rectangle to aRectangle.

**destX**

Answer the x-coordinate of the destination origin.

**destX**: anInteger

Set the x-coordinate of the destination origin to anInteger.

**destY**

Answer the y-coordinate of the destination origin.

**destY**: anInteger

Set the y-coordinate of the destination origin to anInteger.

**drawFrom**: startPoint to: stopPoint

Draw a line from startPoint to stopPoint.

**extent**

Answer a point whose coordinates are the width and height of the transfer area.

**extent**: aPoint

Set the width and height of the transfer area to the coordinates of aPoint.

**height**

Answer the height of the transfer area.
**height**: anInteger

Set the height of the transfer area to anInteger.

**mask**

Answer the mask form which provides the halftone effect.

**mask**: mask

Set the mask (halftone) form to mask.

**sourceForm**

Answer the source form of the receiver.

**sourceForm**: aForm

Set the source form of the receiver to aForm.

**sourceOrigin**: aPoint

Set the origin of the source rectangle to aPoint.

**sourceRect**: aRectangle

Set the source rectangle to aRectangle.

**sourceX**

Answer the x-coordinate of the source origin.

**sourceX**: anInteger

Set the x-coordinate of the source origin to anInteger.

**sourceY**

Answer the y-coordinate of the source origin.

**sourceY**: anInteger

Set the y-coordinate of the source origin to anInteger.

**width**

Answer the width of the transfer area.

**width**: anInteger

Set the width of the transfer area to anInteger.

## Bitmap

A Bitmap is a fixed size indexable sequence of integers in the range 0 through 255. The elements of a Bitmap are efficiently packed into memory, one per byte. They represent bit maps of forms.

Inherits From: FixedSizeCollection IndexedCollection Collection Object

Inherited By: (None)

This class contains indexed byte values.

Class Variables:

(None)
Pool Dictionaries: (None)

Class Methods: (None)

Instance Methods:

**atAllPut: aByte**

Replace the bytes of the receiver with aByte. Answer aByte.

**replaceFrom: start**

**to: stop with: aString startingAt: repStart**

Replace the bytes of the receiver at index positions start through stop with consecutive bytes of aString beginning at index position repStart. Answer the receiver.

**replaceFrom: start to: stop withObject: aByte**

Replace the bytes of the receiver at index positions start through stop with aByte. Answer aByte.

Boolean

Class Boolean is an abstract class which defines the common protocol for logical values. The
logical values are represented by its two subclasses, True and False.

Inhabits From: Object

Inherited By: False True

Named Instance Variables: (None)

Class Variables:

(None)

Pool Dictionaries: (None)

Class Methods: (All private)

Instance Methods:

**deepCopy**

Answer a copy of the receiver with shallow copies of each instance variable. Because
there is only one true and one false, answer the receiver.

**printOn: aStream**

Append the ASCII representation of the receiver to aStream.

**shallowCopy**

Answer a copy of the receiver which shares the receiver instance variables. Because
there is only one true and one false, answer the receiver.
**storeOn:** aStream

Answer the receiver. Append the character sequence of the receiver to aStream from which the receiver can be reconstructed.

## ByteArray

A ByteArray is a fixed size indexable sequence of integers in the range 0 through 255. The elements of a ByteArray are efficiently packed into memory, one per byte.

Inherits From: FixedSizeCollection IndexedCollection Collection Object

Inherited By: FileHandle

This class contains indexed byte values.

**Class Variables:**

(None)

Pool Dictionaries: (None)

Class Methods: (None)

**Instance Methods:**

**replaceFrom:** start

**to:** stop with: aCollection startingAt: repStart

Replace the elements of the receiver at index positions start through stop with consecutive elements of aCollection beginning at index position repStart. Answer the receiver.

## Character

Class Character defines the protocol for all the characters in the system (ASCII codes from 0 to 255). Instances of this class are immutable, meaning that they cannot be removed and new ones cannot be created. There is one and only one instance of each character in Smalltalk.

Inherits From: Magnitude Object

Inherited By: (None)

**Named Instance Variables:**

**asciiInteger**

Contains the ASCII encoding of the character.
Class Variables:

(None)

Pool Dictionaries:

**CharacterConstants**

Defines variables for some of the most frequently used characters (e.g., Space for the space character, Lf for the line-feed character, etc.).

Class Methods:

**digitValue:** anInteger

Answer the character representation of the digit anInteger.

**new**

Disallow the instantiation of characters because characters are immutable.

**value:** anInteger

Answer the character whose ASCII encoding matches anInteger.

Instance Methods:

**<** aCharacter

Answer true if the receiver ASCII value is less than the ASCII value of aChararacter, else answer false.

**< =** aChararacter

Answer true if the receiver ASCII value is less than or equal to the ASCII value of aChararacter, else answer false.

**=** aChararacter

Answer true if the receiver ASCII value is equal to the ASCII value of aChararacter, else answer false.

**>** aChararacter

Answer true if the receiver ASCII value is greater than the ASCII value of aChararacter, else answer false.

**> =** aChararacter

Answer true if the receiver ASCII value is greater than or equal to the ASCII value of aChararacter, else answer false.

**asciiValue**

Answer the number corresponding to the ASCII encoding of the receiver.

**asLowerCase**

Answer the lower case value of the receiver if it is a letter, else answer the receiver.

**asUpperCase**

Answer the upper case value of the receiver if it is a letter, else answer the receiver.

**deepCopy**

Answer a copy of the receiver with shallow copies of each instance variable. Because characters are immutable (cannot instantiate a copy), answer the receiver.
**digitValue**

Answer a number corresponding to the digit value of the receiver.

**hash**

Answer the integer hash.

**isAlphaNumeric**

Answer true if the receiver is in the range of characters from 0 to 9 or in the range from a to z or in the range from A to Z, else answer false.

**isDigit**

Answer true if the receiver is in the range of characters from 0 to 9, else answer false.

**isLetter**

Answer true if the receiver is in the range of characters from a and z or in the range from A and Z, else answer false.

**isLowerCase**

Answer true if the receiver is in the range of characters from a to z, else answer false.

**isSeparator**

Answer true if the receiver character is either a space, tab, carriage-return, line-feed or form-feed character, else answer false.

**isUppercase**

Answer true if the receiver is in the range of character from A to Z, else answer false.

**isVowel**

Answer true if the receiver is any one of the characters a,A,e,E,i,I,o,O,u,U, else answer false.

**printOn: aStream**

Append the ASCII representation of the receiver to aStream.

**shallowCopy**

Answer a copy of the receiver which shares the receiver instance variables. Because characters are immutable (cannot instantiate a copy), answer the receiver.

**storeOn: aStream**

Append the ASCII representation of the receiver to aStream from which the receiver can be reconstructed.

## CharacterScanner

The function of this class is to convert characters represented by ASCII values into displayable bit patterns. It contains a font describing the bit patterns of all characters and carries out the conversion operation by transferring bits from the font (as the source form) to the destination form.

**Inhabits From:**

BitBlt Object
Inherited By: (None)

Named Instance Variables:

**backColor**

Contains a mask form whose contents are used as the color of the background of
characters.

**blankBitBlt**

Contains a BitBlt used to blank a designated area.

**clipHeight**

(From class BitBlt)

**clipWidth**

(From class BitBlt)

**clipX**

(From class BitBlt)

**clipY**

(From class BitBlt)

**destForm**

(From class BitBlt)

**destX**

(From class BitBlt)

**destY**

(From class BitBlt)

**font**

Contains the font used for displaying characters.

**foreColor**

Contains a mask form whose contents are used as the color of the characters.

**frame**

Contains a Rectangle limiting the area on the destination form to receive the
converted bit patterns. Normally the clipping rectangle is the same as this frame
but sometimes can be made smaller for special purposes and then restored to be
the same as the frame.

**halftone**

(From class BitBlt)

**height**

(From class BitBlt)

**rule**

(From class BitBlt)

**sourceForm**

(From class BitBlt)

**sourceX**

(From class BitBlt)

**sourceY**

(From class BitBlt)

**textEnd**

Contains an integer specifying the ending character in the textString to be
displayed.
**textPos**

Contains an integer specifying the starting character in the textString to be displayed.

**textString**

Contains a String of characters to be displayed on the destination form.

**width**

(From class BitBlt)

Class Variables:

(None)

Pool Dictionaries: (None)

Class Methods: (None)

Instance Methods:

**blank:** aPoint **width:** anInteger

Paint to the background color, the rectangle whose origin is aPoint, width is anInteger, and height is the font height.

**blankRestFrom:** anInteger

Blank the bottom portion of the frame starting from anInteger row.

**clipRect:** aRectangle

Set the clipping rectangle of the receiver.

**display:** aString **at:** aPoint

Display the bit pattern of aString at aPoint in the frame of the receiver.

**display:** aString **from:** anInteger **at:** aPoint

Display the bit pattern of aString starting at index position anInteger up to the last character of the string at aPoint in the frame. The remaining line after the last character will be blanked.

**display:** aString

**from:** start **to:** stop **at:** aPoint

Display the bit pattern of aString from index position start to stop at aPoint in the frame of the receiver.

**displayAll:** aCollection

**from:** firstLine **to:** lastLine **at:** columnIndex

Display the part of aCollection between firstLine and lastLine.

**displayForm:** aForm

**at:** aPoint **rule:** aRule

Display aForm at aPoint in the frame using aRule.

**font**

Answer the current font used by the receiver.
**frame**

Answer the framing rectangle of the receiver. Usually it is the same as the clipping rectangle while the latter is sometimes changed to a smaller rectangle.

**gray:** aRectangle

Color aRectangle in the frame with gray tone.

**initialize:** aRectangle **font:** aFont

Initialize the instance variables of the receiver such that its clipping rectangle is aRectangle and the font is aFont. The destination form is assumed to be the display screen.

**initialize:** aRectangle

**font:** aFont **dest:** aForm

Initialize the instance variables of the receiver such that its clipping rectangle is aRectangle, the font is aFont, and the destination form is aForm.

**recover:** aRectangle

Reverse the color of aRectangle in the frame.

**reframe:** aRectangle

Change the frame of the receiver.

**reverse:** aRectangle

Reverse the color of aRectangle in the frame.

**setFont:** aFont

Change the current font to aFont.

**setterForeColor:** fColor **backColor:** bColor

Set the foreground color to fColor and background color to bColor. They can be either an integer color or a mask form.

**show:** aString

**from:** start at: aPoint

Display the bit pattern of aString from index position start at aPoint in the frame of the receiver.

**Class**

Class Class is the superclass of all class classes (i.e. metaclasses) in Smalltalk. It provides the common protocol for defining and accessing class variables and pool dictionaries. The subclass creation messages are implemented here as well. Every class is an instance of a metaclass of the same name. The class contains the instance methods while the metaclass contains the class methods.

**Inhabits From:** Behavior Object

**Inherited By:** (None)
## Named Instance Variables:

**classPool**

Contains a Dictionary of all the class variables defined by this class. The keys are strings containing the class variable names and the values are the current values of the class variables.

**comment**

(From class Behavior)

**dictionaryArray**

(From class Behavior)

**instances**

(From class Behavior)

**name**

(From class Behavior)

**sharedPools**

Contains an Array of symbols for the pool dictionary names referred to by this class.

**structure**

(From class Behavior)

**subclasses**

(From class Behavior)

**superClass**

(From class Behavior)

## Class Variables:

**InstIndexedBit**

(From class Behavior)

**InstNumberMask**

(From class Behavior)

**InstPointerBit**

(From class Behavior)

Pool Dictionaries: (None)

## Class Methods:

**sortBlock**

Answer a sort block for sorting classes alphabetically.

## Instance Methods:

**addClassVarName**: aString

Add a new class variable named aString to the receiver.

**addSharedPool**: aSymbol

Add the shared pool named aSymbol to the receiver shared pool references.

**classPool**

Answer the dictionary containing the class variables defined in the receiver.
**classVarNames**

Answer a Set of class variable names defined in the receiver.

**edit**

Open a ClassBrowser window on the receiver.

**fileOutOn: aStream**

Append the class definition message for the receiver to aStream.

**initialize**

Initialize the class variables defined in the receiver. Subclasses usually override this message. The default is to set all class variables to nil.

**name**

Answer a String containing the receiver name.

**removeFromSystem**

Remove the receiver from Smalltalk. Report an error if there are any subclasses or instances of the receiver.

**rename: aString**

Rename the receiver to aString.

**sharedPools**

Answer an Array of symbols of pool dictionary names referred to by the receiver.

**subclass: classSymbol**

**instanceVariableNames:** instanceVariables

**classVariableNames:** classVariables **poolDictionaries:** poolDictNames

Create or modify the class classSymbol to be a subclass of the receiver with the specified instance variables, class variables, and pool dictionaries.

**variableByteSubclass: classSymbol**

**classVariableNames:** classVariables **poolDictionaries:** poolDictNames

Create or modify the class classSymbol to be a variable byte subclass of the receiver with the specified class variables and pool dictionaries.

**variableSubclass: classSymbol**

**instanceVariableNames:** instanceVariables

**classVariableNames:** classVariables **poolDictionaries:** poolDictNames

Create or modify the class classSymbol to be a variable subclass of the receiver with the specified instance variables, class variables, and pool dictionaries.

**ClassBrowser**

Class ClassBrowser implements a window on all the methods for a single class. Methods can be browsed, edited and cross-referenced. A ClassBrowser window consists of three panes. The first contains the type of methods being browsed (instance or class). The second contains the list of method selectors for the selected type. And the third contains the source code for the selected method. The window's label shows the class name being browsed.

**Inhabits From:** Object
**Inherited By:** (None)

**Named Instance Variables:**

**browsedClass**

Contains the class on which the browser was opened.

**selectedDictionary**

Contains browsedClass or browsedClass class, depending upon whether instance or class methods are selected.

**selectedMethod**

Contains the selector of the selected method, or nil if no method is selected.

**Class Variables:**

(None)

**Pool Dictionaries:** (None)

**Class Methods:** (None)

**Instance Methods:**

**openOn: aClass**

Create a class browser window on aClass. Define the type, behavior and relative size of each pane and schedule the window.

## ClassHierarchyBrowser

Class Hierarchy Browser implements a window on all the classes in Smalltalk/V. It allows for class definitions and methods to be browsed and edited; the source code for a class to be written to a file; and the senders and implementors of messages to be displayed. A ClassHierarchyBrowser window consists of five panes. The first contains the class hierarchy. The second contains the method selectors for the selected class. The third contains the source code for the selected method or the class definition method for the selected class. The fourth and fifth panes are mutually exclusive, containing the type of the method dictionary selected (instance methods or class methods).

**Inhabits From:** Object

**Inherited By:** (None)

**Named Instance Variables:**

**browsedClasses**

Contains an OrderedCollection of strings of class names with the subclasses indented to show the hierarchy.

**hiddenClasses**

Contains a Set of classes whose subclasses should not be displayed. These classes have an ellipsis (...) appended to their name in the hierarchy.
**instanceSelectedLast**

Contains true if the instance pane was selected last, false if the class pane selected last.

**methodSelectedLast**

Contains true if a method selector was selected last, false if a class name was selected last.

**originalClasses**

Contains the collection of classes passed as the argument to the openOn: message.

**selectedClass**

Contains the most recently selected class, or nil if no class is selected.

**selectedMethod**

Contains the most recently selected method selector, or nil if no method is selected.

**Class Variables:**

(None)

**Pool Dictionaries:**

(None)

**Class Methods:**

(None)

**Instance Methods:**

**openOn: aCollection**

Create a class hierarchy browser window giving access to the classes in aCollection and their subclasses.

**ClassReader**

A ClassReader supports Smalltalk source code reading and installation (compilation) from a stream, and writing to a stream. The source code is in 'chunk' format (See Chapter 13, Maintaining Smalltalk/V, for a definition of chunk). A ClassReader is used for writing the entire source code of a class to a file, for reading a file to define a class, and for reading portions of a file to selectively recover methods (for example, using the DiskBrowser to read the change log).

**Inhabits From:**

Object

**Inherited By:**

(None)

**Named Instance Variables:**

**class**

Contains the class to be worked on by the ClassReader.

**Class Variables:**

(None)
### Pool Dictionaries:

#### CharacterConstants

Defines variables for some of the most frequently used characters (e.g., Space for the space character, Lf for the line-feed character, etc.).

### Class Methods:

#### forClass: aClass

Answer an instance of the receiver for aClass.

### Instance Methods:

#### fileInFrom: aStream

Read chunks from aStream until an empty chunk (a single '!' is found. Compile each chunk as a method for the class described by the receiver. Log the source code of the method to the change log.

#### fileOutOn: aStream

File out all the methods for the class described by the receiver to aStream, in chunk format.

## Collection

Class Collection is the superclass of all the collection classes. It is an abstract class defining the common protocol for all of its subclasses. Collections are the basic data structures used to store objects in groups in either a linear or nonlinear fashion (e.g. hashed). This class provides the protocol to directly access (or store) a particular element in a collection, to access all the elements of a collection in a particular order, or to perform some block of code for each element accessed.

**Inhabits From:** Object

**Inherited By:**
* Array Bag
* Bitmap
* CentArray
* CompiledMethod
* Dictionary
* FileHandle
* FixedSizeCollection
* IdentityDictionary
* IndexedCollection
* Interval
* MethodDictionary
* OrderedCollection
* Process Set
* SortedCollection
* String
* Symbol
* SymbolSet
* SystemDictionary

**Named Instance Variables:** (None)

### Class Variables:

(None)

**Pool Dictionaries:** (None)
Class Methods:

**with:** anObject

Answer a collection with only one element, anObject.

**with:** firstObject **with:** secondObject

Answer a collection of two elements, firstObject and secondObject.

**with:** firstObject **with:** secondObject **with:** thirdObject

Answer a collection of three elements, firstObject, secondObject, and thirdObject.

**with:** firstObject

**with:** secondObject **with:** thirdObject **with:** fourthObject

Answer a collection of four elements, firstObject, secondObject, thirdObject, and fourthObject.

Instance Methods:

**add:** anObject

Answer anObject. Add anObject to the receiver collection.

** addAll : aCollection

Answer aCollection. Add each element of aCollection to the elements of the receiver.

**asArray**

Answer an Array containing all the elements of the receiver.

**asBag**

Answer a Bag containing the elements of the receiver.

**asOrderedCollection**

Answer an OrderedCollection containing the elements of the receiver.

**asSet**

Answer a Set containing the elements of the receiver.

**asSortedCollection**

Answer a SortedCollection containing the elements of the receiver sorted in ascending order.

**asSortedCollection : aBlock**

Answer a SortedCollection containing the elements of the receiver sorted according to aBlock.

**collect : aBlock**

For each element in the receiver, evaluate aBlock with that element as the argument. Answer a new collection containing the results as its elements from the aBlock evaluations.

**deepCopy**

Answer a copy of the receiver with shallow copies of each element.

**detect : aBlock**

Answer the first element of the receiver that causes aBlock to evaluate to true (with that element as the argument). If no such element is found, report an error.
**detect:** aBlock ifNone: exceptionBlock

Answer the first element of the receiver that causes aBlock to evaluate to true (with that element as the argument). If no such element is found, evaluate exceptionBlock (with no arguments).

**do:** aBlock

For each element in the receiver, evaluate aBlock with that element as the argument. This method should be implemented in the class of the receiver.

**includes:** anObject

Answer true if the receiver contains an element equal to anObject, else answer false.

**inject:** initialValue into: aBinaryBlock

For each element in the receiver collection, evaluate aBinaryBlock with that element as the argument. Starting with initialValue, the block is also provided with its own value from the previous evaluation. Answer this value at the end of the block evaluations.

**isEmpty**

Answer true if the receiver collection contains no elements, else answer false.

**notEmpty**

Answer true if the receiver collection contains one or more elements, else answer false.

**occurrencesOf:** anObject

Answer the number of elements contained in the receiver collection that are equal to anObject.

**printOn:** aStream

Append the ASCII representation of the receiver to aStream.

**reject:** aBlock

For each element in the receiver, evaluate aBlock with that element as the argument. Answer a new collection containing those elements of the receiver for which aBlock evaluates to false.

**remove:** anObject

Answer anObject. Remove the element equal to anObject from the receiver collection. If such an element is not found, report an error.

**remove:** anObject ifAbsent: aBlock

Answer anObject. Remove an element equal to anObject from the receiver collection. If such an element is not found, evaluate aBlock (with no arguments).

**removeAll:** aCollection

Answer aCollection. Remove all the elements contained in aCollection from the receiver collection.

**select:** aBlock

For each element in the receiver, evaluate aBlock with that element as the argument. Answer a new collection containing those elements of the receiver for which aBlock evaluates to true.
**shallowCopy**

Answer a copy of the receiver which shares the receiver elements.

**storeOn: aStream**

Append the ASCII representation of the receiver to aStream from which the receiver can be reinstantiated.

**ColorForm**

A ColorForm contains an array of bitmaps. All bits in the same location of each bitmap collectively represent the color of the pixel at that location.

**Inherits From:**

Form DisplayMedium DisplayObject Object

**Inherited By:**

(None)

**Named Instance Variables:**

**bits**

(From class Form)

**byteWidth**

(From class Form)

**deviceType**

(From class Form)

**height**

(From class Form)

**offset**

(From class Form)

**width**

(From class Form)

**Class Variables:**

**BlackMask**

(From class Form)

**DarkGrayMask**

(From class Form)

**GrayMask**

(From class Form)

**LightGrayMask**

(From class Form)

**PrinterMode**

(From class Form)

**WhiteMask**

(From class Form)

**Pool Dictionaries:**

(None)
**Class Methods:**

**color:** aColor
Answer a mask form filled with aColor.

**new**
Answer a new ColorForm.

**Instance Methods:**

**at:** aPoint
Answer the color for pixel at aPoint.

**byteValueAtX:** xInteger **Y:** yInteger
Answer the byte at the position specified by the point (xInteger @ yInteger) in the first plane.

**compatibleForm**
Answer the class of internal form most similar to the receiver.

**compatibleMask**
Answer the class of mask form most suitable for use with the receiver.

**width:** wInteger **height:** hInteger **initialByte:** aByte
Change the receiver width to wInteger and height to hInteger, and initialize every byte in the bitmap to aByte.

**width:** wInteger **height:** hInteger **initialColor:** aColor
Change the receiver width to wInteger and height to hInteger, and fill with aColor.

## ColorScreen

A ColorScreen is like a DisplayScreen except that it has multiple planes (like ColorForm) and thus support multiple colors.

**Inhabits From:** DisplayScreen Form DisplayMedium DisplayObject Object

**Inherited By:** (None)

**Named Instance Variables:**

**bits**
(From class Form)

**byteWidth**
(From class Form)

**deviceType**
(From class Form)

**height**
(From class Form)

**offset**
(From class Form)
**width**

(From class Form)

**Class Variables:**

**BackColor**

(From class DisplayScreen)

**BlackMask**

(From class Form)

**DarkGrayMask**

(From class Form)

**GrayMask**

(From class Form)

**HighResIBeam**

(From class DisplayScreen)

**LightGrayMask**

(From class Form)

**LowResIBeam**

(From class DisplayScreen)

**Mode**

(From class DisplayScreen)

**PrinterMode**

(From class Form)

**WhiteMask**

(From class Form)

**Pool Dictionaries:** (None)

**Class Methods:** (None)

**Instance Methods:**

**compatibleForm**

Answer the class of internal form most similar to the receiver.

**compatibleMask**

Answer the class of mask form most suitable for use with the receiver.

**refreshColor**

Load the default color palette.

**Commander**

A Commander commands an Array of pens. When it receives a pen related message, it passes the operation to every pen under its command. When a Commander is in action, it gives the illusion that all of its pens are operating simultaneously.

**Inhabits From:** Pen BitBlt Object
Inherited By: (None)

## Named Instance Variables:

**clipHeight**

(From class BitBlt)

**clipWidth**

(From class BitBlt)

**clipX**

(From class BitBlt)

**clipY**

(From class BitBlt)

**destForm**

(From class BitBlt)

**destX**

(From class BitBlt)

**destY**

(From class BitBlt)

**direction**

(From class Pen)

**downState**

(From class Pen)

**fractionX**

(From class Pen)

**fractionY**

(From class Pen)

**halftone**

(From class BitBlt)

**height**

(From class BitBlt)

**pens**

Contains an Array of pens being commanded.

**rule**

(From class BitBlt)

**sourceForm**

(From class BitBlt)

**sourceX**

(From class BitBlt)

**sourceY**

(From class BitBlt)

**width**

(From class BitBlt)

## Class Variables:

**DoubleCenter**

(From class Pen)

Pool Dictionaries: (None)
**Class Methods:**

**new:** `anInteger`

Answer aCommander initialized to anInteger number of pens.

**Instance Methods:**

**clipRectAll:** `aRectangle`

Set the clipping rectangle of every pen to aRectangle.

**destX**

Answer the x coordinate of the first pen.

**destY**

Answer the y coordinate of the first pen.

**direction:** `anInteger`

Set the direction of every pen to anInteger number of degrees.

**down**

Set all the pens down.

**ellipse:** `anInteger` **aspect:** `aFraction`

Make each pen draw an ellipse with aspect ratio aFraction.

**fanOut**

Change the direction of each pen by an increment of 360 / number of pens.

**go:** `anInteger`

Move all pens a distance of anInteger in their current direction.

**goto:** `aPoint`

Move the first pen to aPoint and then move the remaining pens by the same distance and direction as the first move.

**lineUpFrom:** `startPoint` **to:** `endPoint`

Place all the pens on equi-distant points on the line defined by startPoint and endPoint.

**location**

Answer a Point indicating the position of the first pen.

**place:** `aPoint`

Set the position of the first pen to aPoint and modify the position of the remaining pens by the amount of change in the first pen. No drawing takes place.

**turn:** `anInteger`

Change the direction of all the pens by anInteger number of degrees.

**up**

Lift all the pens.
## CompiledMethod

A CompiledMethod is produced by the Smalltalk/V compiler and interpretively executed by the Smalltalk/V virtual machine.

**Inhabits From:** Array FixedSizeCollection IndexedCollection Collection Object

**Inherited By:** (None)

This class contains indexed instance variables.

**Named Instance Variables:**

**byteCodeArray**

Contains a ByteArray with codes to be executed.

**class**

Contains the class whose method dictionary contains the method.

**primitive**

Contains the user primitive number, or zero if none.

**selector**

Contains a Symbol representing the message selector.

**Class Variables:**

(None)

**Pool Dictionaries:** (None)

**Class Methods:** (All private)

**Instance Methods:** (All private)

## Compiler

Class Compiler is used for converting Smalltalk source code to compiled methods and for evaluating Smalltalk expressions. There are no instances of this class because its behavior is entirely defined with class messages.

**Inhabits From:** Object

**Inherited By:** LCompiler

**Named Instance Variables:** (None)

**Class Variables:**

(None)
Pool Dictionaries: (None)

Class Methods:

**compile: aString in: aClass**

Compile the method aString in aClass. If the method compiles correctly, answer an Association whose key is the method selector and whose value is the compiled method. If not, answer nil and report the error on the Transcript.

**compile: aString**

**in: aClass notifying: requestor ifFail: exceptionBlock**

Compile the method aString in aClass. If the method compiles correctly, answer an Association whose key is the method selector and whose value is the compiled method. If not, send the messages: requestor compilerError: errorString at: position in: codeString for: aClass. exceptionBlock value.

**evaluate: aString**

Compile and evaluate the method ('Doit', aString) in the context of UndefinedObject. If the method compiles correctly, answer the result of the evaluation. If not, report the error on the Transcript and answer nil.

**evaluate: aString**

**in: aClass to: doitReceiver notifying: requestor ifFail: exceptionBlock**

Compile and install the method ('Doit', aString) in aClass. If the method compiles correctly, answer: doitReceiver Doit. If not, send the messages: requestor compilerError: errorString at: position in: aString. exceptionBlock value. In any case remove the selector `#Doit` from aClass' method dictionary.

**positionsOf: aString in: aClass**

Answer highlighting information for source aString in class aClass.

**positionsOf: aString**

**in: aClass notifying: requestor ifFail: exceptionBlock**

Answer highlighting information for source aString in class aClass. If compile error, notify requestor and evaluate exceptionBlock.

Instance Methods: (None)

Context

A Context is used to describe the execution state of blocks of code (enclosed in square brackets). They are the objects to which value, value:, value:value: messages are sent to start block evaluation.

Inherited From: Object

Inherited By: HomeContext
Named Instance Variables:

**blockArgumentCount**

Contains an integer representing the number of block arguments.

**homeContext**

Contains the first context for the method, which includes the method arguments and temporaries as indexed instance variables.

**startPC**

Contains an integer which is the initial program counter for the block.

Class Variables:

(None)

Pool Dictionaries: (None)

Class Methods: (None)

Instance Methods:

**fork**

Create and schedule a new process for the expressions in the receiver block, at the current priority.

**forkAt: aNumber**

Create and schedule a new process for the expressions in the receiver block, at priority aNumber.

**homeContext**

Answer the home context.

**value**

Answer the result of evaluating the no argument block described by the receiver.

**value: anObject**

Answer the result of evaluating the one argument block described by the receiver.

**value: arg1 value: arg2**

Answer the result of evaluating the two argument block described by the receiver.

**whileFalse: aBlock**

Repetitively evaluate the receiver block and aBlock, until the result of receiver block evaluation is true. Answer nil.

**whileTrue: aBlock**

Repetitively evaluate the receiver block and aBlock, until the result of receiver block evaluation is false. Answer nil.
## CursorManager

An instance of CursorManager contains the bit pattern to display a cursor shape. In addition, it contains the methods for managing the moving, hiding, and displaying of the cursor. This class serves as an interface between the Smalltalk code and the mouse driver when a mouse driver is loaded in the memory.

**Inhabits From:**

Object

**Inherited By:**

NoMouseCursor

**Named Instance Variables:**

**hotSpot**

Contains a Point relative to the top left corner of the cursor shape which aligns the cursor image to the cursor position on the display screen.

**image**

Contains a String of the cursor image in the format required by the Microsoft mouse when the mouse driver is loaded. Contains a Form of the cursor image when the mouse driver is not loaded.

**Class Variables:**

**NoMouse**

Contains a Boolean indicating whether the mouse driver is loaded (false) or not (true).

**Position**

Contains a Point representing the cursor position on the display screen.

**Pool Dictionaries:**

**CharacterConstants**

Defines variables for some of the most frequently used characters (e.g., Space for the space character, Lf for the line-feed character, etc.).

**Cursors**

Defines variables for the various cursor shapes.

**FunctionKeys**

Defines variables for the function key codes (of class Character) input from the keyboard or mouse.

**Class Methods:**

**corner**

Answer the corner cursor.

**crossHair**

Answer the cross hair cursor.

**downArrow**

Answer the down arrow cursor.
**execute**

Answer the hour glass cursor.

**hand**

Answer the hand cursor.

**leftArrow**

Answer the left arrow cursor.

**normal**

Answer the arrow cursor.

**origin**

Answer the origin cursor.

**rightArrow**

Answer the right arrow cursor.

**scroll**

Answer the scroll cursor.

**upArrow**

Answer the up arrow cursor.

Instance Methods:

**change**

Change Cursor to be the receiver.

**display**

Display the receiver on the screen.

**hide**

Hide the cursor from the screen.

**hotSpot**

Answer the hot spot of the receiver cursor.

**initForm: aForm hotSpot: aPoint**

Initialize the contents of the receiver cursor from aForm (mask on top of cursor shape) using aPoint as its hot spot.

**initialize: aForm hotSpot: aPoint**

Initialize the contents of the receiver cursor from aForm using aPoint as its hot spot.

**isThereInput**

Answer true if there is input from keyboard or mouse, else answer false.

**offset**

Answer a copy of the cursor position.

**offset: aPoint**

Set the cursor position to aPoint. Answer the new position.
# Date

A Date represents a particular day since the start of the Julian calendar. Class Date defines the protocol for creating, comparing, and computing dates.

**Inhabits From:** Magnitude Object

**Inherited By:** (None)

**Named Instance Variables:**

**day**

Contains the number of days from January 1, 1901 up to the date represented by this instance.

**Class Variables:**

**MonthNames**

Contains a Dictionary. The keys of the dictionary are instances of class Symbol representing the month names in both the full and abbreviated form. For each of the keys, the corresponding value is an integer from 1 to 12 indicating the index of the month in the year.

**MonthStrings**

Contains a Dictionary. The keys of the dictionary are instances of class String representing the month names in both the full and abbreviated form. For each of the keys, the corresponding value is an instance of class Symbol representing the name of the month in the abbreviated 3 character form.

**Pool Dictionaries:** (None)

**Class Methods:**

**calendarForMonth:** aSymbol year: anInteger

Answer a String containing the formatted calendar for the month name aSymbol in the year anInteger.

**dateAndTimeNow**

Answer an Array of two elements. The first element is a Date representing the current date and the second element is a Time representing the current time.

**dayOfWeek:** aSymbol

Answer a number from 1 to 7 indicating the weekday number for aSymbol (1 meaning Monday, to 7 meaning Sunday).

**daysInMonth:** aSymbol forYear: anInteger

Answer the total number of days for the month aSymbol in the year yInteger.

**daysInYear:** anInteger

Answer the total number of days for the year anInteger.
**fromDays:** anInteger

Answer a Date that is anInteger number of days before or after January 1, 1901
depending on the sign of anInteger.

**fromString:** aString

Answer a Date specified by aString. aString contains first the day number then
the month name and then the year separated with blanks.

**indexOfMonth:** aSymbol

Answer a number from 1 to 12 indicating the month index for the aSymbol.

**leapYear:** anInteger

Answer true if the year anInteger is a leap year, else answer false.

**leapYearsTo:** anInteger

Answer the number of leap years from 1901 to the year number before anInteger.

**monthNameFromString:** aString

Answer a Symbol for a month name corresponding to the month name in aString.

**nameOfDay:** anInteger

Answer the weekday name as a Symbol corresponding to the weekday index
anInteger (Monday for index 1, to Sunday for index 7).

**nameOfMonth:** anInteger

Answer the month name as a Symbol corresponding to the month index anInteger
(January for index 1, to December for index 12).

**newDay:** dInteger **month:** aSymbol **year:** yInteger

Answer a Date of the day dInteger in the month aSymbol for the year yInteger.

**newDay:** dInteger **year:** yInteger

Answer a Date of the day dInteger in the year yInteger.

**today**

Answer the current date.

Instance Methods:

**<** aDate

Answer true if the receiver is before aDate.

**< =** aDate

Answer true if the receiver is before or the same as aDate.

**=** aDate

Answer true if the receiver is the same as aDate.

**>** aDate

Answer true if the receiver is after aDate.

**> =** aDate

Answer true if the receiver is the same or after aDate.

**addDays:** anInteger

Answer a Date that is anInteger number of days after the receiver.
**asSeconds**

Answer the number of seconds that have elapsed from January 1, 1901 to the receiver.

**day**

Answer the number of days from the receiver to January 1, 1901.

**dayIndex**

Answer a number from 1 to 7 indicating the weekday number of the receiver (1 meaning Monday, to 7 meaning Sunday).

**dayName**

Answer the name of the weekday of the receiver.

**day Of Month**

Answer a number from 1 to 31 indicating the day number within the month of the receiver.

**day Of Year**

Answer a number from 1 to 366 indicating the day within the year of the receiver.

**daysInMonth**

Answer the total number of days for the receiver month.

**daysInYear**

Answer the total number of days for the receiver year.

**daysLeftInMonth**

Answer number of days remaining in the receiver month.

**daysLeftInYear**

Answer number of days remaining in the receiver year.

**elapsedDaysSince: aDate**

Answer the number of elapsed days between the receiver and aDate.

**elapsedMonthsSince: aDate**

Answer the number of elapsed months between the receiver and aDate.

**elapsedSecondsSince: aDate**

Answer the number of elapsed seconds between the receiver and aDate.

**firstDayInMonth**

Answer the number of the first day in the receiver month relative to the beginning of the receiver year.

**firstDay Of Month**

Answer a Date representing the first day in the receiver month.

**formPrint**

Answer a string representing the receiver Date in the form: mm/dd/yy.

**hash**

Answer the integer hash value for the receiver.

**monthIndex**

Answer a number from 1 to 12 indicating the month of the receiver.
**monthName**

Answer a Symbol representing the month name of the receiver.

**previousWeekday**: aSymbol

Answer a Date reflecting the most recent day name represented by aSymbol preceding the receiver.

**printOn**: aStream

Append the ASCII representation of the receiver to aStream in the form: mmm dd, yyyy. (The form yyyy is satisfied only for positive year numbers of 4 digits).

**subtractDate**: aDate

Answer the number of days between the receiver and aDate.

**subtractDays**: anInteger

Answer the date that is anInteger number of days before the receiver Date.

**year**

Answer the year number of receiver Date.

# Debugger

A Debugger is a window application which allows debugging a Process in two different windows: a single pane walkback window and a six pane debugger window. The Debugger initially creates a walkback window. If requested via the `~debug~` menu choice, the walkback window is replaced with the debug window. The debug window allows the debugged process to be resumed from the point of interruption or restarted by resending a selected message. Traced execution can be controlled by hop, skip, and jump buttons in the window label.

**Inhabits From**: Inspector Object

**Inherited By**: (None)

**Named Instance Variables:**

**breakpointArray**

Contains an Array of pairs of classes and selectors for methods which have breakpoints set.

**breakpoints**

Contains a SortedCollection of methods which have breakpoints set.

**browseWalkback**

Contains true if browsing the walkback and false if browsing breakpoints.

**instIndex**

(From class Inspector)

**instList**

(From class Inspector)

**instPane**

(From class Inspector)
**label**

Contains a String used to give a debugger window the same label as a walkback window

**method**

Contains the selected CompiledMethod or nil if none.

**methodPane**

Contains a TextPane which contains the method source.

**object**

(From class Inspector)

**positions**

Contains information for highlighting the method source.

**process**

Contains the Process object being debugged.

**resumable**

Contains true if the process is resumable, otherwise false.

**source**

Contains a String representing the source code of the selected method.

**stream**

Contains (1) a ReadStream for scanning the source of the selected method or (2) a WriteStream used to generate walkback lines for the debug window.

**temps**

Contains an OrderedCollection of lines containing the names of temporary variables for the selected method.

**walkback**

Contains an OrderedCollection of walkback lines for the debug window.

**walkbackIndex**

Contains the index of the selected walkback line or nil if none.

Class Variables:

(None)

Pool Dictionaries:

(None)

Class Methods:

(None)

Instance Methods:

**walkbackFor: aProcess label: aString**

Pop-up a walkback window with label equal to aString). Display the stacked message sends for the receiver in the window.

**walkbackLabel: aString**

Pop-up a walkback window with the label equal to aString. Display the stacked message sends for the current process in the window.

DeletedClass

An instance of deleted class is used to replace classes removed from the system.
Inherits From: Object

Inherited By: (None)

Named Instance Variables: (None)

Class Variables:

(None)

Pool Dictionaries: (None)

Class Methods: (None)

Instance Methods: (None)

# DemoClass

This class demonstrates graphics and animation.

Inherits From: Object

Inherited By: (None)

Named Instance Variables:

### pen

Contains a Pen for drawing the demonstrations.

### rectangle

Contains a Rectangle which limits the drawing area.

Class Variables:

### Count

Contains an integer used as the current drawing color.

Pool Dictionaries: (None)

Class Methods: (None)

Instance Methods:

### bounceBall

Display a bouncing ball where speed of the ball depends on the position of the cursor.

### demoMenu

Answer the menu for the receiver.
**dragon**

Draw a dragon pattern.

**dragon: anInteger**

Draw a dragon pattern where anInteger is the recursion factor.

**mandala**

Draw a mandala.

**multiEllipse**

Draw 5 ellipses.

**multiMandala**

Draw 8 mandalas.

**multiPentagon**

Draw multiple pentagons.

**multiPolygon: anInteger**

Draw multiple polygons where each polygon has anInteger number of sides.

**multiSpiral**

Draw 4 spirals.

**run**

Initialize and start the animation demonstration.

**walkLine**

Draw a rotating line.

**Dictionary**

A Dictionary is a collection of key/value pairs of objects. The keys in a dictionary are unique, whereas values may be duplicated. A Dictionary may be searched either by key or by value. Key searches use hashing for efficiency. Elements may be entered into and extracted from a dictionary either as a pair of objects (e.g., `at:put:`) or as an Association (e.g., `add:`). Internally, a Dictionary stores the key/value pairs as a set of associations whereas an `IdentityDictionary` stores the key/value pairs in successive array elements (see `IdentityDictionary`).

**Inherited From:** Set Collection Object

**Inherited By:** IdentityDictionary MethodDictionary SystemDictionary

**Named Instance Variables:**

**contents**

(From class Set)

**elementCount**

(From class Set)
Class Variables:

(None)

Pool Dictionaries: (None)

Class Methods: (None)

Instance Methods:

**add:** anAssociation

Answer anAssociation. Add anAssociation to the receiver.

**associationAt:** aKey

Answer the Association whose key equals aKey from the receiver. If not found, report an error.

**associationAt:** aKey ifAbsent: aBlock

Answer the Association whose key equals aKey from the receiver. If not found, evaluate aBlock (with no arguments).

**associationsDo:** aBlock

Answer the receiver. For each key/value pair in the receiver, evaluate aBlock with that pair as the argument.

**at:** aKey

Answer the value of the key/value pair whose key equals aKey from the receiver. If not found, report an error.

**at:** aKey ifAbsent: aBlock

Answer the value of the key/value pair whose key equals aKey from the receiver. If not found, evaluate aBlock (with no arguments).

**at:** aKey put: anObject

Answer anObject. If the receiver contains the key/value pair whose key equals aKey, replace the value of the pair with anObject. Else add the aKey/anObject pair.

**deepCopy**

Answer a copy of the receiver with shallow copies of each element.

**do:** aBlock

Answer the receiver. For each value in the receiver, evaluate aBlock with that value as the argument.

**includes:** anObject

Answer true if the receiver contains the key/value pair whose value equals anObject, else answer false.

**includesKey:** aKey

Answer true if the receiver contains aKey, else answer false.

**inspect**

Open a dictionary inspector window on the receiver.
**keyAtValue: anObject**

Answer the key in the receiver whose paired value equals anObject. If not found, answer nil.

**keyAtValue: anObject ifAbsent: aBlock**

Answer the key in the receiver whose paired value equals anObject. If not found, evaluate aBlock (with no arguments).

**keys**

Answer a Set containing all the keys in the receiver.

**keysDo: aBlock**

Answer the receiver. For each key in the receiver, evaluate aBlock with the key as the argument.

**occurrencesOf: anObject**

Answer the number of key/value pairs in the receiver, whose values are equal to anObject.

**remove: anObject ifAbsent: aBlock**

Remove the key/value pair whose value is anObject from the receiver dictionary. This method reports an error since the values are not unique in a dictionary, the keys are.

**removeAssociation: anAssociation**

Answer the receiver after anAssociation has been removed from it. If anAssociation is not in the receiver, report an error.

**removeKey: aKey**

Answer the receiver with the key/value pair whose key equals aKey removed. If such a pair is not found, report an error.

**removeKey: aKey ifAbsent: aBlock**

Answer aKey. Remove the key/value pair whose key equals aKey from the receiver. If such a pair is not found, evaluate aBlock (with no arguments).

**select: aBlock**

For each key/value pair in the receiver, evaluate aBlock with the value part of the pair as the argument. Answer a new object containing those key/value pairs for which aBlock evaluates to true.

**shallowCopy**

Answer a copy of the receiver which shares the receiver elements.

**storeOn: aStream**

Append the ASCII representation of the receiver to aStream from which the receiver can be reinstantiated.

**values**

Answer a Bag containing all the values of the key/value pairs in the receiver.
## DictionaryInspector

Class DictionaryInspector implements a window on a dictionary which allows the entries of a dictionary to be viewed and changed. The left list pane displays the ASCII representation of all the dictionary keys. The right text pane displays an ASCII representation of the value associated with the selected key.

Inherited From: Inspector Object

Inherited By: (None)

### Named Instance Variables:

**instIndex**
(From class Inspector)

**instList**
(From class Inspector)

**instPane**
(From class Inspector)

**object**
(From class Inspector)

### Class Variables:

(None)

Pool Dictionaries: (None)

Class Methods: (None)

Instance Methods: (All private)

## Directory

A Directory represents a disk directory with a device letter and a path name string. Files are generally described in terms of a directory and a file name. AindeStream may be created by sending the message file: or newFile: to a Directory.

Inherited From: Object

Inherited By: (None)

### Named Instance Variables:

**drive**
Contains a Character representing the disk drive letter.

**pathName**
Contains a String representing the path name (from the root directory) of the directory, not including the drive letter.
**volumeLabel**

Contains a String representing the label of the disk containing the directory.

**Class Variables:**

(None)

**Pool Dictionaries:** (None)

**Class Methods:**

**create:** newPathName

Create a DOS directory on disk with complete path name newPathName.

**current**

Answer a Directory representing the current DOS directory.

**currentDisk**

Answer the current default drive (0 = A, 1 = B, etc.).

**extractDateTimeFrom:** aString

Answer a String in form 'yy-mm-dd hh:mm:ss' describing date and time from DOS directory entry aString.

**extractFileNameFrom:** aString

Answer a string representing the file name from a DOS directory entry aString.

**extractFlagsFrom:** aString

Answer a String containing attribute flags from a DOS directory entry aString.
Attributes are: 'r' read only, 'h' hidden, 's' system, and 'a' archive.

**extractSizeFrom:** aString

Answer the file size extracted from a DOS directory entry aString.

**IFAName:** aString

Answer a Directory described by the complete path name in aString.

**remove:** aString

Remove the DOS directory with the path name of aString.

**Instance Methods:**

**= aDirectory**

Answer true if aDirectory represents the same directory as the receiver, else answer false.

**create**

Create a DOS directory on disk for the receiver directory.

**drive**

Answer the disk drive letter of the receiver.

**drive:** aCharacter

Initialize the drive for the receiver to aCharacter.
**file: aString**

Answer aindeStream for the file named aString in the current directory. If the file
does not exist, it will be created.

**formatted**

Answer a collection of arrays of file information for the receiver directory. Each
array has four entries: file name, size, date/time and attributes.

**freeDiskSpace**

Answer the free space in bytes on the disk containing the current directory.

**hasSubdirectory**

Answer true if the receiver has a subdirectory.

**makeCurrent**

Make the receiver the current DOS directory.

**newFile: aString**

Answer a FileStream for the file named aString in the current directory. If the file
exists, it will be removed and a new file will be created.

**pathName**

Answer a String representing the path name of the receiver directory (drive letter not included).

**pathName: aString**

Set the receiver directory path name to aString.

**remove**

Remove the directory described by the receiver from the disk.

**subdirectories**

Answer an OrderedCollection of arrays, where each Array contains the complete
path name and the file name of a subdirectory of the receiver.

**volumeLabel**

Answer the volume label of the disk containing the receiver.

DiskBrowser

Class DiskBrowser implements a window on the complete directory hierarchy on a disk. It replaces most DOS file commands. Directories can be created, deleted and browsed. Files can be created, deleted, copied, renamed, browsed, printed, edited and their attributes may be modified.

Inherited From: Object

Inherited By: (None)

Named Instance Variables:

**allFileMenu**

Contains the contents pane menu when the entire file has been read.
**contentsPane**

Contains the TextPane used to display file contents.

**device**

Contains the disk drive character.

**directoryIndex**

Contains the index of the selected directory.

**directoryList**

Contains an OrderedCollection of strings describing the directory hierarchy.

**hiddenDirectories**

Contains a set of directories currently being hidden.

**noFileMenu**

Contains the contents pane menu when no file has been read.

**partFileMenu**

Contains the contents pane menu when part of the file has been read.

**pathNameArray**

Contains an Array that parallels directoryList. Each entry contains the complete path name of a directory.

**selectedDirectory**

Contains a Directory for the selected DOS directory, or nil if no directory is selected.

**selectedFile**

Contains a String representing the selected file name, or nil if no file is selected.

**sortCriteria**

Contains a block which describes how to sort the files in a directory: by name, size or creation date/time.

**sortedFileList**

Contains an OrderedCollection of arrays describing the files in the selected directory. Each Array entry has four elements: the file name, size, creation date/time and attributes (mode).

**sortPane**

Contains a ListPane which describes the sort criteria.

**volumeLabel**

Contains a String representation of the volume label.

**wholeFileRequest**

Contains true if the entire file is to be displayed in the text pane, false if only the head and tail are to be displayed.

**Class Variables:**

(None)

**Pool Dictionaries:**

**CharacterConstants**

Defines variables for some of the most frequently used characters (e.g., Space for the space character, Lf for the line-feed character, etc.).

**FunctionKeys**

Defines variables for the function key codes (of class Character) input from the keyboard or mouse.