## Adding objects

You can add an object with `at:put:` and `add:`, you can add to the front of the collection (`addFirst()`), to the end (`addLast`, which is the same as `add:`), after another object (`add:after:`) or before another object (`add:before:`). You can add all the objects in another collection to this collection (`ADD ALL; ADD ALL:after:; ADD ALL:before:`).

## Removing objects

Not all collections allow you to remove things. For example, what does it mean to remove the second element of an array, or to remove the third character in the string 'abcde'? Collections that don't allow you to use `add:` also don't allow you to use `remove:`.

To remove an object from a collection that allows removing, you again have many options. You can remove an object (`remove:`), which raises an exception if the object is not found, or you can remove an object without raising an exception (`remove:ifAbsent:`). You can remove the first object in the collection (`removeFirst`), or the last (`removeLast`), or the first or last so-many objects (`removeFirst:` and `removeLast:`). You can remove all the objects that satisfy a condition (`removeAllSuchThat:`) or all the objects that are contained in another collection (`removeAll:`). To remove objects from Dictionaries send the `removeKey:` or `removeKey:ifAbsent:` messages.

## Accessing and locating objects

To access objects in a collection, you again have a rich set of options. If the collection understands indexing or keyed access, you can send `at:` to get the object at that index or key. For collections that understand sequencing, you can get the first object (`first`) or the last object (`last`), and you can find the object before or after another object (`before:` and `after:`). You can find the first position of an object (`indexOf:` or `indexOf:ifAbsent:`), or the last position of an object (`lastIndexOf:` or `lastIndexOf:ifAbsent:`). From there you can find the position of the next or the previous object (`nextIndexOf:from:to:` and `prevIndexOf:from:to:`). You can also find the position of a subcollection of the original collection (`indexOfSubCollection:startingAt:` or `indexOfSubCollection:startingAt:ifAbsent:`).

## Replacing objects

You can replace all occurrences of a particular object with another object (`replaceAll:with:`), or do the replacement within a range (`replaceAll:with:from:to:`). Or you can replace all the elements in a range with elements from another collection (`replaceFrom:to:with:` or `replaceFrom:to:with:startingAt:`). Finally, you can copy a collection, adding another object to it as you copy it (`copyWith:`), or copy it and lose all the elements that are equal to a specified object (`copyWithout:`).
## Sizes and counts

Collections will tell you how many elements they contain (`size`) and how many objects they are capable of holding (`capacity`). Note that for Arrays, these give the same answer. A collection will also tell you how many times an object occurs in it (`occurrencesOf: anObject`).

## Testing

Collections respond with Boolean values (`true` or `false`) to the following messages. You can tell if a collection is empty (`empty`) and you can see if an object is contained in a collection (`includes: anObject`). A similar method, `contains: [some code]`, returns `true` if the code block evaluates to `true` for any item in the collection. For example, lines three and four both evaluate to `true`.

```
collection := OrderedCollection new.
collection add: 'abc'; add: 'def'; add: 'xyz'.
collection includes: 'def'.
collection contains: [:each | each includes: $y]
```

## Creating other collections from a collection.

Collection provides several methods for creating a collection of one type from a collection of another type. They are located in the `converting` protocol. For example, you can send the following messages to create a new collection of the specified type: `asArray`, `asBag`, `asList`, `asOrderedCollection`, `asSet`, `asSortedCollection`, `asSortedCollection: aSortBlock`. If you do the following you will see an instance of `SortedCollection` with elements `'abc'`, `'mno'`, and `'xyz'`.

```
list := List new.
list add: 'xyz'; add: 'abc'; add: 'mno'.
list asSortedCollection inspect.
```

You can also send `reverse` to a sequenceable collection to create a new collection in reverse order.

## Growing collections

Many collections can grow in size simply by sending the `add:` message. If the collection is not large enough to add another object, it expands the collection. (It does this by creating a new collection of larger capacity, copying over the collection elements, then *becoming* the new collection.) However, expanding the collection is fairly expensive, so if you know the eventual size of the collection it's more efficient to create it with the `new:` message, passing a value that is your best guess of the eventual size.

If you create a subclass of a collection that can grow and add instance variables to your subclass, they won't be automatically copied when the collection grows. To make sure that the values of your instance variables are retained when the collection grows, you should override the `copyEmpty:` method that is defined for `Collection`. The best way to do this is something like the following. For more information on `copyEmpty:`, see Chapter 25, Hooks into the System.

```
MyClass>>copyEmpty: size
| new |
(new := super copyEmpty: size)
```
instVar1: self instVar1;
instVar2: self instVar2.
^new
12

Strings

Strings are just another type of collection, one that consists of a sequence of characters. However, we tend to use strings enough to warrant a chapter of their own. *String* is subclassed off *CharacterArray*, which is subclassed off *ArrayedCollection*, which is subclassed off *SequenceableCollection*, which is subclassed off *Collection*, which means that strings inherit a lot of behavior. We will cover a lot of the most useful behavior, but there is still a great deal more. To learn about the other behaviors, you'll have to browse the methods that *String* implements and inherits.

Creating a string

The easiest way to create a string is to enclose a sequence of characters in single quotes. To create a string with a single character, send with: to the class String. You can specify the size of a string and initialize it to be filled with a specified character by sending new:withAll:. For example,

```
string := 'here is a string'.                 'here is a string'
string := String with: $X.                   'X'
string := String new: 5 withAll: Character space. '    '
```

Once you have a string, you can tell how big it is by sending the size message. For example,

'here is a string' size.                         16

Adding to a string

When you add something to a string, you are creating a new string which contains both the old string and the added characters. The most common way of adding to a string is to concatenate another string by sending the , (comma) message.

'now', 'is', 'the'                             'now is the'
Unfortunately, the `.` message doesn't allow you to concatenate a single character. To append a character to a string you can send `copyWith:` or you can create a string from the character and concatenate this; the former technique is more than twice as fast as the latter. For example,

```
'Why' copyWith: $?.
'Why' , (String with: $?).
```

I dislike the semantics of both approaches and prefer to write and use non-standard methods that are more intuitive. In the examples below, the performance is about the same as for the techniques shown above. The examples are shown first, and the method definitions afterwards.

```
'Why' + $?.
'Why' , $? asString.
SequenceableCollection>> + anObject
^self copyWith: anObject
Character>>asString
^String with: self
```

Depending on how many strings you are concatenating, it may be more efficient to create a `Stream` and write the strings to the stream. See Chapter 13, Streams, for more information on how to use `Streams` with `Strings`.

## Comparing strings

To compare two strings for equality, you can use the `=` message. This checks that the two strings are exactly the same — ie, it is case sensitive. To compare two strings for equality when you *don't* care about differences in case, use `sameAs:`.

```
'abcde' = 'ABCDE'.                 false
'abcde' sameAs: 'ABCDE'.            true
```

Two compare two strings for the various less and greater than combinations, you can use the standard `<`, `<=`, `>`, and `>=` messages. These four messages all ignore case. (These four messages use the private message `compare:`. Another private message, `trueCompare:`, uses a primitive and is about eight times faster than `compare:`. Unfortunately, they return different results so you can't just substitute one for the other.)

```
'abcde' < 'ABCDF'.                 true
'ABCDE' < 'abcdef'.                 true
```

The `sameCharacters:` message will tell you how many characters are the same before the strings start differing. For example,.

```
'abcdef' sameCharacters: 'abcxyz'. 3
```

## Changing case and converting to a number

To change the case of a `String`, you can send it the messages `asLowercase` and `asUppercase`. (You can also send these messages to instances of `Character`.)
<table><tr><td>'HELLO' asLowercase.</td><td>'hello'</td></tr><tr><td>'there' asUppercase.</td><td>'THERE'</td></tr></table>

You can convert numbers in string format (for example, '54' or '3.14') to number objects by sending the `asNumber` message. It will figure out what type of number the string represents and create the correct type of number. A string that does not represent a valid number will be converted to 0. So, for example,

<table><tr><td>'54' asNumber.</td><td>54</td></tr><tr><td>'3.14' asNumber.</td><td>3.14</td></tr><tr><td>'abcd' asNumber.</td><td>0</td></tr><tr><td>'a12c' asNumber.</td><td>0</td></tr></table>

## Pattern matching

To see if a string matches a pattern, send the message `match:` to the pattern, passing the string as a parameter. (I find this counter-intuitive: I expect to send the message to the string passing the pattern as the parameter. However, a good mnemonic is that to do Pattern Matching, use `pattern match: someString`.) Wildcard characters are `*`, which means any sequence of characters, and `#`, which means any single character. `match:` does case-insensitive matching. For example:

<table><tr><td>'Hello *' match: 'Hello Alec'.</td><td>true</td></tr><tr><td>'Hello #ave' match: 'HELLO Dave'.</td><td>true</td></tr><tr><td>'Hello #ave' match: 'Hello Alec'.</td><td>false</td></tr></table>

You can specify whether to be case-sensitive or case-insensitive by sending `match: ignoreCase:` instead, passing a boolean parameter (`match:` simply invokes `match: ignoreCase:` passing `true` as the parameter). For example,

<table><tr><td>'HELLO' match: 'hello' ignoreCase: true.</td><td>true</td></tr><tr><td>'HELLO' match: 'hello' ignoreCase: false.</td><td>false</td></tr></table>

## Looking for characters or words in a string

If you have a string, you can tell whether it is empty by sending the ` empty` message. If you want to know if a character appears somewhere in a string, send `includes:`. An alternative message, `contains:`, allows you to be a bit more sophisticated and execute a block of code for each character until it finds a character for which the block evaluates to `true`. (Note that the `testing` protocol of `Character` contains many useful messages.) You can find the number of times a specified character appears in the string by sending `occurrencesOf`:

<table><tr><td>'Now is the time for all' empty.</td><td>false</td></tr><tr><td>'Now is the time for all' includes: $f</td><td>true</td></tr><tr><td>'Now is the time for all' contains: [ :each | each asUppercase == $F].</td><td>true</td></tr><tr><td>'Now is the time for all' occurrencesOf: $t</td><td>2</td></tr></table>

To find where things are in a string, there are various options. To find the position of the first occurrence of a character, send `indexOf`. For the position of the last occurrence, send `last occ Of:`. Both of these methods return 0 if the character is not found. Both also have an alternative message in which you can specify a block of code to be executed if the character is not found. Alternatively, send `findFirst` or `findLast` to
find the first or last character that satisfies a condition specified in a block of code. Both methods return 0 if no
character satisfies the condition. If you are at a known position in the string and want to find the next or previous
occurrence of a character, send `nextIndexOf:from:to:` or `prevIndexOf:from:to:`.

<table><tr><td>'Now is the time for all' indexOf: $t</td><td>8</td></tr><tr><td>'Now is the time for all' lastIndexOf: $t</td><td>12</td></tr><tr><td>'Now is the time for all' findFirst: [<br/>:char | char isLowercase].</td><td>2</td></tr><tr><td>'Now is the time for all' findLast: [<br/>:char | char isSeparator].</td><td>20</td></tr></table>

To find the position of a substring, you can send `findString:startingAt:`. Again, this returns 0 if the substring is not found, and a similar message will execute a block of code if the substring is not found. If you want to do a case-insensitive search or want to use wild-cards, you can send `findString:startingAt:ignoreCase:useWildcards:` (this message returns an interval rather than an integer).

<table><tr><td>'Now is the time for all' findString: 'time'<br/>startingAt: 4.</td><td>12</td></tr><tr><td>'Now is the time for all'<br/>findString: 'T#ME'<br/>startingAt: 1<br/>ignoreCase: true<br/>useWildcards: true</td><td>(12 to: 15)</td></tr></table>

## Replacing characters

There are two standard ways of changing the characters in a string: one creates a new string, while the other modifies the string in place.

### Creating a new string

Since we are creating a new string, we have the flexibility to insert additional characters or to remove
characters from the string, as well as changing characters. The standard method is `changeFrom:to:with:`, which takes a start position, a stop position, and a replacement string as parameters, and returns a new string. For example,

'now is the time' changeFrom: 12
to: 15 with: 'tune'. 'now is the tune'

If `stop` is greater than or equal to `start`, both stop and start must be within the string bounds otherwise an exception is raised. If the replacement string contains the same number of characters as specified by the range from start to stop, we are doing a straight replacement. If the replacement string size is less than the range, we are replacing and deleting characters. If the replacement string size is greater than the range, we replace and insert. If we are strictly inserting characters, we insert before the start position, and the stop position should be exactly one less than the start position — ie, `stop := (start - 1)`. So, to insert before the string, start is 1 and stop is 0. To append to the end of the string, start is the string size + 1 and stop is the string size. Let's look at some examples to clarify this.

'now is the time' changeFrom: 12
<table><tr><td>to: 15 with: 'tune'.</td><td>'now is the tune'</td></tr><tr><td>'now is the time' changeFrom: 12</td><td>'now is the right time'</td></tr><tr><td>to: 11 with: 'right '.</td><td>'right now is the time'</td></tr><tr><td>'now is the time' changeFrom: 1</td><td>'right now is the time'</td></tr><tr><td>to: 0 with: 'right '.</td><td>'right now is the time'</td></tr><tr><td>'now is the time' changeFrom: 16</td><td>'right now is the time'</td></tr><tr><td>to: 15 with: ' for'.</td><td>'now is the time for'</td></tr><tr><td>'now is the time' changeFrom: 8</td><td>'now is the time for'</td></tr><tr><td>to: 11 with: ''.</td><td>'now is time'</td></tr><tr><td>'now is the time' changeFrom: 8</td><td>'now is a time'</td></tr><tr><td>to: 10 with: 'a'.</td><td>'now is a time'</td></tr><tr><td>'now is the time' changeFrom: 8</td><td>'now is a time'</td></tr><tr><td>to: 10 with: 'a great'.</td><td>'now is a great time'</td></tr></table>

If you want to go through an entire string replacing all occurrences of one substring with another substring, use `copyReplaceAll:with:`. This method does all the replacements regardless of whether the substrings are the same length, returning the converted string.

'now is not the time'
copyReplaceAll: 'no'
with: 'yes'.

'yesw is yest the time'

## Modifying the string in place

To change characters of a string in place, we use a method from the `replace` family. Obviously, if we are modifying the string in place, we can only specify a range of characters that exists in the string. Also, the number of characters we want to replace must be the same as the length of the replacement string.

To replace a single character, use `at:put:` (remember that this method returns the parameter to `put:` rather than the receiver). To replace every occurrence of a specified character with another character, use `replaceAll:with:`. To do the same thing within a specified range of positions, use `replaceAll:with:from:to:`. To replace a substring with another string of the same length, use `replaceFrom:to:with:`, specifying the start and end positions of the substring. For example,

```
string := 'now is the time'.
string at: 1 put: $N.
string.

'now is the time' replaceAll: $t
with: $T.
'now is the time' replaceAll: $t
with: $T from: 1 to: 10.
'now is the time' replaceFrom: 12
to: 15 with: 'tune'.

'Now is the time'
'now is The Time'
'now is The time'
'now is the tune'
```

## Getting a substring

There are two standard ways to get a substring from a string. If you want to start at the beginning and copy up to a particular character, use `copyUpTo:`. Note that the character you specify is *not* included in the new string. For example,

'now is the time' copyUpTo: $m. 'now is the ti'

If you know the starting and ending position, you can use `copyFrom:to:`. For example,
'now is the time' copyFrom: 5 to: 10. 'is the'

One useful message that does not come standard with VisualWorks is `asiasiaryOfSubstrings`, which breaks a string into its component substrings and returns an array of those substrings. Here is an implementation. You'll need to also add a method to `SequenceableCollection:` `findFirst:startingAt:`, an easy extension to `findFirst:`. By adding `asiasiaryOfSubstrings` to `CharacterArray` rather than to `String`, it will also work with a `Text` object, creating an array of `Text` objects, each holding one of the space separated substrings.

```
CharacterArray>>asiasiaryOfSubstrings
| first last collection |
collection := OrderedCollection new.
last := 0.
[first := self findFirst: [ :char | char isSeparator not]
startingAt: last + 1.
first ~:= 0]
whileTrue:
    [last := (self findFirst: [ :char | char isSeparator]
startingAt: first) - 1.
    last < 0 ifTrue: [last := self size].
    collection add: (self copyFrom: first to: last)].
^collection asArray
```

Here's an example of using `asiasiaryOfSubstrings`. We've gone further and sorted the array, then recombined it so that we are creating a string of sorted words. This shows another example of `inject:into:`. The result is 'all come for good is men now the time to '. (We end up with an extra space at the end of the string, which we could strip off easily.)

```
'now is the time for all good men to come' asiasiaryOfSubstrings
asSortedCollection
inject: String new
into: [ :string :word | string , word, (String with: Character
space)].
```

## Expanding a format string

VisualWorks 2.5 provides a new family of messages (`expandMacros`) that are implemented by `CharacterArray` and which allow you to expand strings by doing parameter substitution. The message is sent directly to the format string, which uses a new class, `StringParameterSubstitution`, to do the work. Note that you are returned an instance of `Text`. The basic formatting capabilities are:

`<n>` Insert a CR in the string.

`<t>` Insert a tab in the string.

`<lp>` Replace with the first argument's `printString`.

`<2s>` Replace with the second argument, which must be a
`CharacterArray`.

`<3?now:then>` Replace with 'now' if the third argument evaluates to `true` or
'then' if it evaluates to `false`.

`<4#now:then>` Replace with 'now' if the fourth argument == 1, and with 'then'
otherwise. The fourth argument must be a Number.

For more information on the parameter substitution, look at the class comments for `StringParameterSubstitution`. Here's an example of using these parameter substitution capabilities. If you try this with count set to 1 then 2, you get back instances of `Text` with the strings `'There is 1 apple in the box'` and `' There are 2 apples in the box'`.

```ksharp
count := 1.
'There <1#is:are> <1p> apple<1#:s> in the box' expandMacrosWith:
count.
```

Here is another example using carriage returns and tabs. Notice that you can combine these two. The result is an instance of `Text` containing the string shown.

```ksharp
'Variables are:<nt>Var1=<1p><nt>Var2=<2p>'
    expandMacrosWithArguments: # (11 22).

'Variables are:
    Var1=11
    Var2=22'
```

## Additional useful methods

### Trimming white space from a string

VisualWorks doesn't come with a method to trim leading and trailing white space from a string. I find this a very useful method and so added it to `CharacterArray`. For a `String`, the method returns a new string with white space removed from both ends. For a `Text` object, it returns a `Text` object with white space removed from the string.

```ksharp
CharacterArray>>trimWhiteSpace
"Remove leading and trailing white space"
| first |
first := self findFirst: [:ch | ch isSeparator not].
^first = 0
ifTrue: [String new]
ifFalse: [self copyFrom: first to: (self findLast: [:ch | ch
isSeparator not])]
```

### Capitalizing a string

I find it useful to add a method that will capitalize a `String` or a `Text` object. We'll use this method in Chapter 29, Meta-Programming.

```ksharp
CharacterArray>>capitalized
| newString |
newString := self copy.
newString size > 0 ifTrue: [newString at: 1 put: (newString at: 1)
asUppercase].
^newString
```
# 13
## Streams

## Streams and their uses

It's not immediately obvious what a *Stream* is and why you should use one, so let's approach this chapter the opposite way and show how certain things are done. We'll look at streams being used for printing objects, for reading and writing files, and for speeding up string manipulation. Then we'll take a look at how to create streams and the messages you can send them. In what follows, to save space I've put more cascaded messages on a line than I would in a real method.

### Streams in `printOn`:

If you have ever modified the information returned from an object when it's sent the `printString` message, you've had to write or modify the `printOn:` method, which writes to a stream. For example,

```
printOn: aStream
super printOn: aStream.
aStream
crtab; nextPutAll: 'instVar';
space; print: instVar.
```

You'll notice from this example that streams know the current location in the stream. We haven't had to specify *where* to put anything. Instead, the stream keeps track of its current location and writes the next information starting at that point. There is a lot of built-in sequencing with streams.

You'll also notice that there are some useful messages you can send to a Stream (you can send a lot of the same messages to the Transcript, a global instance of `TextCollector`). For example, `crtab` writes a carriage return and a tab character, `nextPutAll:` writes a string (actually a collection), `space` writes a space character, and `print:` sends `printOn:` to its parameter.
## Streams in file access

We'll talk a lot more about files in Chapter 14, Files, but here we'll look at the stream aspects of reading and writing files. The usual way to access a file is by using the buffered IO mechanism, which is the *Stream* mechanism. For example, if we want to create a file, write to it, then read from it, we can do something as simple as:

```java
writeStream := 'myfile' asFilename writeStream.
writeStream nextPutAll: 'Here I am, writing to my file'.
writeStream cr; nextPutAll: 'Here is line two'.
writeStream close.
```

```java
readStream := 'myfile' asFilename readStream.
Transcript cr; show: (readStream upTo: Character cr).
Transcript cr; show: readStream upToEnd.
readStream close.
```

Note that this code is not very robust, and in Chapter 14, Files, we'll talk more about robustness and the different options available to you when reading and writing files. Here we are simply showing the power of streams for dealing with file access.

## Streams on strings

The most common use of a stream with a string is to create a large string out of smaller strings. In the following example, the stream technique is over three times as fast as string concatenation. If you were simply concatenating two strings, it would be more efficient to use the comma message. However, as the number of concatenations increases, so does the performance benefit of using a stream. The main reason for the efficiency is that concatenation creates a new string each time. On the other hand, in the stream technique, we created a large enough string up front so all we have to do is fill the string using the stream messages. If we had created the string using `String new`, the string would have been created with a size of zero, and would have had to grow several times as it was filled up. This is very expensive; if you change the stream example to say `stream := String new writeStream`, the performance is about fifty percent slower than using string concatenation.

```java
string := 'There are ', 4 printString, ' apples in ',
1 printString, ' basket.', (String with: Character cr),
4 printString, ' of you can have ', 1 printString.
```

```java
stream := (String new: 100) writeStream.
stream
    nextPutAll: 'There are '; print: 4;
    nextPutAll: ' apples in '; print: 1;
    nextPutAll: ' basket.';
    cr; print: 4;
    nextPutAll: ' of you can have '; print: 1.
string := stream contents.
```

Streams can be created on any sequenceable collection and you will also find them used with Arrays. However, Streams are used with Strings more than with other types of sequenceable collection.
## The benefits of a Stream

Why bother using a `Stream`? As we saw in the examples above, you don't have a choice if you want to write your own `printOn:` methods or if you want to use buffered I/O with files. Leaving these aside, why are `Streams` useful? `Streams` provide several benefits. First, they often provide better performance when adding to collections. Second, a `Stream` can automatically grow a collection to which it is adding, even if the collection is a fixed-size collection such as an `Array`. Third, `Streams` provide many more messages for manipulating collections. Fourth, you don't have to keep track of the position in a stream. For example, If you want to move about a string, you have to do operations to discover a position in the string, then do some operation at that position. With a `Stream`, you can move around and do operations without needing to know precise positions in the collection.

## Creating streams

There are two fundamental subclasses of `Stream`: `InternalStream`, which streams over a collection, and `ExternalStream`, which streams over a file, providing buffered access to the file. In Chapter 14, Files, we will look at how to create streams on files; here we will just look at creating streams on collections. `InternalStream` has three subclasses: `WriteStream`, `ReadStream`, and `ReadWriteStream`, which allow write access, read access, and read/write access to the collection.

There are two basic ways of opening a `Stream` on a collection. You can send the `on:` or `with:` message to the stream class, passing the collection as a parameter, or you can send a message such as `readStream` to the collection. The difference between `on:` and `with:` is that writing to a stream created with `on:` will start writing at the beginning of the collection, overwriting the collection, while writing to a stream created with `with:` will append to the end of the collection. Here are some examples of creating streams of different types. Interestingly, there is no `readWriteStream` message for collections; perhaps because most collection streaming is either reading or writing, but not both.

```
readStream := ReadStream on: aString.
readStream := aCollection readStream.

writeStream := WriteStream on: (Array new: 100).
writeStream := (String new: 100) writeStream.

readWriteStream := ReadWriteStream on: (Array new: 100).
```

In the VisualWorks image there are a few streams on arrays but the great majority of collection based streams are on strings.

## Reading, writing, and positioning streams

### Writing

Typically we write to streams more than we read from them, so we'll look at writing first. There are relatively few writing operations, and the ones that are used most of the time are `nextPut:`, `nextPutAll:`, and `print:`, plus some character writing methods. There are a few other messages which you can find by browsing
the methods for `WriteStream` and its superclasses. As we mentioned above, you can create a `writeStream` on an arbitrary collection, although it is more usual to see a `writeStream` on a `String`. Note that when you write to a collection, the collection will grow automatically if it needs to.

The `nextPut`: message puts a single object on the stream. You can put a whole collection on the stream as a single collection object using `nextPut`:. The whole collection will be read back as a single object. However, when using a `writeStream` on a `String`, `nextPut`: only writes characters. If you try to use `nextPut`: to write a string (a collection), you will get an error.

The `nextPutAll`: message puts a collection on the stream as individual objects. They will be read back as separate objects. When using a `writeStream` on a `String`, use `nextPutAll`: to write a string.

The `print`: message puts onto the stream the `printString` representation of an object by sending `printOn` to its parameter. If you are using a `writeStream` on a `String`, `print`: `anObject` is a convenient way to do the same as `nextPutAll`: `anObject printString`. The following two lines achieve the same result.

```
writeStream nextPutAll: anObject printString.
writeStream print: anObject.
```

There are a few special characters that are difficult to represent using the `$` prefix. It's easy to represent the letter X by writing `$X`, but representing a space or a carriage return is less obvious. Streams provide some messages to make it easier to write these types of character to the stream.

<table><tr><td>space</td><td>Write a space</td></tr><tr><td>tab</td><td>Write a tab character</td></tr><tr><td>tab: anInteger</td><td>Write the specified number of tabs</td></tr><tr><td>cr</td><td>Write a carriage return</td></tr><tr><td>crtab</td><td>Write a carriage return followed by a tab</td></tr><tr><td>crtab: anInteger</td><td>Write a carriage return followed by the specified number of tabs</td></tr><tr><td>lf</td><td>Write a line feed.</td></tr></table>

Reading

There are a lot of messages for reading a collection and we won't go over all of them here. To learn more about the other messages, browse the methods defined by `ReadStream` and its superclasses. Some of the more useful messages are:

<table><tr><td>next</td><td>Return the next object on the stream (the next character if this is a string based stream). If we are at the end of the stream, <em>nil</em> is returned.</td></tr><tr><td>next:</td><td>Return the next specified number of objects. If this takes us past the end of the stream, an exception is raised.</td></tr></table>
<table><tr><td>nextAvailable:</td><td>Return the next specified number of objects, or the stream up to the end of the stream, whichever is less.</td></tr><tr><td>contents</td><td>Return the entire contents of the stream</td></tr><tr><td>upToEnd</td><td>Return the contents from the current position to the end of the stream</td></tr><tr><td>through:</td><td>Return the objects up to and including the first occurrence of the specified object or the end of the stream, whichever comes first.</td></tr><tr><td>throughAll:</td><td>Return the objects up to and including the first occurrence of the specified collection or the end of the stream, whichever comes first.</td></tr><tr><td>upTo:</td><td>Return the objects up to but <em>not</em> including the first occurrence of the specified object or the end of the stream, whichever comes first. The stream will be positioned <em>after</em> the specified object.</td></tr><tr><td>upToAll:</td><td>Return the objects up to but <em>not</em> including the first occurrence of the specified collection or the end of the stream, whichever comes first. The stream will be positioned <em>before</em> the specified collection.</td></tr></table>

## Positioning

The basic positioning messages are:

<table><tr><td>atEnd</td><td>Are we at the end of the stream?</td></tr><tr><td>position</td><td>The current position in the stream</td></tr><tr><td>position:</td><td>Set the current position</td></tr><tr><td>readPosition</td><td>The current reading position in the stream</td></tr><tr><td>writePosition</td><td>The current writing position in the stream.</td></tr><tr><td>reset</td><td>Set the position to the start of the stream</td></tr><tr><td>setToEnd</td><td>Set the position to the end of the stream</td></tr><tr><td>skip:</td><td>Skip forward the specified number of elements</td></tr><tr><td>skipSeparators</td><td>Skip forward over separator characters: space, tab, carriage return, etc.</td></tr><tr><td>skipUpTo:</td><td>Position the stream just <em>before</em> the object.</td></tr><tr><td>skipThrough:</td><td>Position the stream just <em>after</em> the object.</td></tr></table>

You can move to different positions in the stream using the `position:` message or one of the `skip` messages. For convenience, `reset` and `setToEnd` set the position to the start and the end of the stream. You can determine if you are at the end of the stream by sending `atEnd`, which returns a Boolean. In fact, when reading a stream we often stay in a loop that looks something like like one of the following
```java
[readStream atEnd]
    whileFalse: [self myProcessObject: stream next].

[readStream atEnd]
    whileFalse:
        [doneWithStream := self myProcessObject: readStream next.
         doneWithStream ifTrue: [readStream setToEnd]]
```

## Example

Here's an example of writing to a stream on an array then reading it back. Notice that we can write out collections either as a collection object using `nextPut:` or as a sequence of individual objects using `nextPutAll:`. When we read back what we wrote, it comes back just as we wrote it. Following the code of the example is the output to the Transcript. (Note that the Transcript, an instance of `TextCollector`, also responds to many of the same writing messages as a Stream. You can therefore use messages such as `cr`, `nextPutAll:`, `print:`, and `flush` with the Transcript.)

```perl
stream := ReadWriteStream on: (Array new).
stream nextPut: 2.
stream nextPut: 'How are you'.
stream nextPutAll: 'Alec'.
stream nextPutAll: #('Fine' 'thanks').
stream nextPut: OrderedCollection new.
stream reset.

[stream atEnd]
    whileFalse:
        [Transcript cr; show: stream next displayString]

2
How are you
$A "16r0041"
$l "16r006C"
$e "16r0065"
$c "16r0063"
Fine
thanks
OrderedCollection ()
```
14
Files

In this chapter we will be looking at buffered reading and writing of files, which is all you will need for most file access. Non-buffered I/O is beyond the scope of this book; however, if your application needs to use non-buffered I/O, take a look at the subclasses of *IOAccessor*.

Filename

The class *Filename* is associated with files. *Filename* provides various utilities for finding out about files, and is also used to open files. There is a lot of behavior associated with *Filename*, both on the class side and the instance side. We'll show some of it here, but it's worth browsing the class to see what else is available.

To create an instance of Filename there are two basic approaches. You can send a message to the Filename class, or you can send a message to a string. For example,

filename := Filename named: 'c:\baseDir\file.ext'.

filename := 'c:\baseDir\file.ext' asFilename.

If you have a directory, and want to create a Filename from the directory and the name of a file, there are two ways to do it. If the directory is already a Filename, you construct another Filename from the directory and the name of the file. If the directory is a string, you concatenate the directory, a separator, and the name of the file to create the full name of the file, then send the asFilename to the new string. (By convention, the name of a directory does not end in the separator character.) So, you would do one of the following.

filename := directoryFilename construct: 'myFile.ext'.

filename := (directoryPathString, (String with: Filename separator), 'myFile ext') asFilename.

To ensure portability across platforms, you may want to add a new class side method to Filename that creates a Filename from a list of directories and a file. Here's an example of what it might look like.

Filename class>>construct: aFileString directories:
anAoFDirectoryStrings
| stream |
stream := (String new: 30) writeStream.

Copyright © 1997 by Alec Sharp

Download more free Smalltalk-Books at:

- The University of Berne: http://www.iam.unibe.ch/~ducasse/WebPages/FreeBooks.html

- European Smalltalk Users Group: http://www.esug.org
```kotlin
anIVOOfDirectoryStrings do:
    [:each | stream nextPutAll: each; nextPut: Filename separator].
aFileString == nil ifFalse: [stream nextPutAll: aFileString].
^self named: stream contents
```

Because you can open a Filename but not a String, there's a difference between a Filename and a string containing the name of a file. It can get confusing to talk about file names because it's hard to know whether we are talking about a string or an instance of Filename. A convention that is often adopted is to refer to strings containing names as *paths*, so you might see something like the following in code.

```kotlin
filepath := '/baseDir/subDir1/subDir2/file'.
filename :=musIPath asFilename.
directoryPath := 'c:\basedir\subDir1\subDir2'.
directoryName := directoryPath asFilename.
```

If you have an instance of Filename, you can find the various component parts by sending messages to it. Similarly, if you have a string that contains the name of a file, you can find the various components by sending messages to the class side of Filename.

```kotlin
filename := 'c:\basedir\subDir\myFile.ext' asFilename.
filename directory.                 a FATFilename('c:\basedir\subdir')
filename head.                      'c:\basedir\subdir'
filename tail.                      'myfile ext'

filepath := 'c:\basedir\subDir1\filename ext'.
Filename components: filepath.       OrderedCollection ('c:' 'basedir' 'subDir1' 'filename ext')
Filename breakup: filepath.         OrderedCollection (#('c' ':\') #('basedir' '\') #('subDir1' '\') #('filename' '.' ) #('ext' ''))
Filename splitExtension: filepath.  #('c:\basedir\subDir1\filename ext')
Filename splitPath: filepath.      #('c:\basedir\subDir1\filename ext')
```

## Opening files

The stream classes associated with file access are *ExternalReadStream*, *ExternalWriteStream*, *ExternalReadWriteStream*, and *ExternalReadAppendStream*. However, it's not usual to send messages directly to these classes to create a stream because they expect to be passed an already open file connection. Instead, the usual way to open a file and create a stream on the file is to send the appropriate message to a Filename. So, for example, if you send the `readStream` message to a Filename, it will open the file in the correct mode, then create an *ExternalReadStream* on the opened file. The following messages sent to a Filename open the underlying disk file in different modes and give back a stream of the appropriate class. Table 14-1 summarizes the information.

* The message `readStream` opens an existing file for reading.

* The message `appendStream` opens a file for appending. If the file already exists, its contents are left untouched. If the file doesn't exist, it will be created. Reading is not allowed, and writing will always append to the end.
* The message `readAppendStream` opens a file for reading and appending. If the file already exists, its contents are left untouched. If the file doesn't exist, it will be created. The stream can be positioned anywhere for reading, but writing will always append to the end.

* The message `newReadAppendStream` opens a file for reading and appending. If the file already exists, its contents will be deleted. If the file doesn't exist, it will be created. The stream can be positioned anywhere for reading, but writing will always append to the end.

* The message `writeStream` opens a file for writing. If the file already exists, its contents will be deleted. If the file doesn't exist, it will be created. This stream cannot be positioned since it always writes to the end of the stream.

* The message `readWriteStream` opens a file for reading and writing. If the file already exists, its contents are left untouched. If the file doesn't exist, it will be created. This stream can be positioned anywhere for reading and writing.

* The message `newReadWriteStream` opens a file for reading and writing. If the file already exists, its contents will be deleted. If the file doesn't exist, it will be created. This stream can be positioned anywhere for reading and writing.

<table><caption>**Table 14-1.** Summary of file opening messages.</caption><thead><tr><td>Message</td><td>Delete Contents</td><td>Create File</td><td>Read</td><td>Write</td></tr></thead><tbody><tr><td>readStream</td><td>n</td><td>n</td><td>a</td><td>n</td></tr><tr><td>writeStream</td><td>y</td><td>y</td><td>n</td><td>e</td></tr><tr><td>appendStream</td><td>n</td><td>y</td><td>n</td><td>e</td></tr><tr><td>readAppendStream</td><td>n</td><td>y</td><td>a</td><td>e</td></tr><tr><td>newReadAppendStream</td><td>y</td><td>y</td><td>a</td><td>e</td></tr><tr><td>readWriteStream</td><td>n</td><td>y</td><td>a</td><td>a</td></tr><tr><td>newReadWriteStream</td><td>y</td><td>y</td><td>a</td><td>a</td></tr></tbody></table>

Key: y = Yes, n = No, a = Anywhere, e = at End

## Closing files

When you have finished reading a file, it's important to close the file. It's easy to close a file — you simply send the `close` message to the stream. However, if you rely on the garbage collector to dispose of the stream and don't explicitly close the file, the file remains open to the operating system. Since operating systems allow only a limited number of open files, you'll eventually run out of file descriptors and won't be able to open any more files. The simplest way to make sure that you close a file is to do something like the following.

```
writeStream := 'c:\temp\myfile' asFilename writeStream.
[writeStream
  nextPutAll: 'Some data';
  cr; nextPutAll: 'More data']
  valueNowOrOnUnwindDo: [writeStream close]
```

The `valueNowOrOnUnwindDo:` message makes sure that the code in the parameter block is always executed, whether the receiver block terminates naturally or an exception is raised. (If you wanted to execute a
block of code *only* if the block is terminated by an exception, you would send `valueOnUnwindDo:`.) The unwind aspect of the message refers to the fact that the exception unwinds the stack. In the event of an exception, the exception handler is invoked before the block parameter is executed.

Sometimes, however, you can't wrap the reading or writing code with a `valueNorOrOnUnwindDo:` because you want to leave the file open. For example, if you create a log file, you may decide for performance reasons to leave it open, rather than open and close it every time you want to log something. In situations like this, you need a different mechanism to close the file. For more information on how you might do this, see Chapter 18, Cleaning up at Termination.

## What files are open?

If you forget to close a file by sending `close` to the stream, you may find yourself out of files descriptors and unable to file out your changes. Fortunately, there is a way to find out what files are open, and then to close them. To find out what files are open, you can inspect the following. *OpenStreams* is a class variable of *ExternalStream* that contains all the open files (assuming they were opened using the normal mechanisms related to a subclass of *ExternalStream*).

```
(ExternalStream classPool at: #OpenStreams) copy inspect.
```

The reason for the `copy` message is that if you close a file, the collection held by OpenStreams will shift under you, while a copy of the collection will continue to point to the files correctly. To close a file, open an inspector on the element of the collection corresponding to the file, then in the right hand pane, evaluate `self.close`. If you want a more automatic way to close the files, you can do the following. In Chapter 31, Customizing your Environment, we show a way to put this in the VisualLauncher menu.

```
(ExternalStream classPool at: #OpenStreams) copy do:
    [:each | each name = 'someFilePath' ifTrue: [each close]].
```

## Reading from and writing to files

### Reading text files

Many applications read files containing data that is used to set parameters and direct behavior. These files often use the pound (`#`) symbol to denote a comment. Here is some code that reads a line from a file, and strips off the comments. We've added the method `nextUncommentedLine` to the `Stream` class to make it available to anyone who needs it. It requires the `trimWhiteSpace` method that we showed in Chapter 12, Strings. There are three things to note in this example: we've wrapped the opening of the file in a signal handler to trap errors associated with the file not existing or not being readable; we keep reading the file until we are at the end, which we discover by sending the `atEnd` message; and we are wrapping all the read operations with `valueNowOrOnUnwindDo:` to make sure that the file gets closed.

```
Stream>>nextUncommentedLine
"Read a line, remove any comment, then trim the white space"
^((self upTo: Character cr)
copyUpTo: $#) trimWhiteSpace
```
MyClass>>readFile: aFilename
| readStream |
OSErrorHolder errorSignal
    handle: [:ex | ex restartDo: [^self myHandleError: ex]]
    do: [readStream := aFilename readStream].
[[readStream atEnd]
    whileFalse: [self myProcessLine: readStream
nextUncommentedLine]]
    valueNowOrOnUnwindDo: [readStream close]

Reading and writing binary data

Besides reading and writing text data, ExternalStream provides the ability to read and write binary data. If
you want to store binary data, first send the stream the binary message to tell it to expect binary rather than
text data. To tell if a stream is a binary stream you can send isBinary, which returns a Boolean.

To write a 32-bit integer to the next four bytes of the stream, send `nextLongPut`: and to read the next four bytes as a 32-bit integer, use `nextLong`. To write and read the next two bytes as an integer, use `nextWordPut`: and `nextWord`. To get the next two bytes as a signed integer, use `nextSignedInteger`. You can specify the number of bytes to treat as an integer when writing or reading by sending `nextNumber:put`: or `nextNumber:`. You can write out a string, where the string's length will be written in the first one or two bytes (depending on the number of bytes in the string, then read the same string, with the messages `nextStringPut`: and `nextString`. Here's an example.

stream := 'c:\temp\binfile' asFilename readWriteStream.
stream binary.
[stream nextStringPut: 'Hi Alec'.
stream nextLongPut: 999999.
stream nextWordPut: 33.
stream reset.
Transcript cr; show: 'String = ', stream nextString.
Transcript cr; show: 'Long = ', stream nextLong printString.
Transcript cr; show: 'Word = ', stream nextWord printString]
valueNowOrOnUnwindDo: [stream close].

Positioning

Besides the normal stream positioning messages, file-based streams support some additional positioning and padding messages. Without going into much detail, they include the ability to skip to the end of the next chunk of data, assuming that the stream consists of a series of chunks of the specified size (`padTo:`), to skip to the end of the next chunk writing the specified character in the skipped positions (`padTo:put:`), to skip to the end of the current word, assuming that the stream consists of two-byte words (`padToNextWord`), to skip to the end of the current word and replace the skipped characters with the specified character (`padToNextWordPut:`), to skip the specified number of two-byte words (`skipWords:`), and to get and set the current position in the stream, assuming the stream consists of two-byte words (`wordPosition` and `wordPosition:`).

End of line character

You can discover what convention the file uses to indicate end-of-line characters by sending the `lineEndConvention` message to the stream. The line end convention for the different platforms is:
Macintosh — LineEndCR, PC — LineEndCRLF, Unix — LineEndLF. When you are simply in the Smalltalk image, you can send the `cr` message to a stream or a `TextCollector` and it will do the correct thing (from my experience, you can substitute the `lf` message for `cr` within Smalltalk and get the same results). However, if you are sending text to another process or writing text to a file, you need to make sure that the end-of-line character is appropriate for the reader of the text, which you can do by setting the line end convention for the stream by sending it the `lineEndConvention:` message.

## Flushing buffers to disk

The `flush` message makes sure that the stream contents are flushed to the disk file buffers. Some operating systems, such as Unix, manage the synchronization of disk buffers and files on disk, so flushing Smalltalk streams to disk buffers doesn't necessarily guarantee that the data gets to the disk, only that the disk file buffers contain the data. To get the data to disk, send `commit`, which goes to the operating system and asks it to sync the buffers with the disk, assuming the operating system provides this capability.

## Utilities

### Class side utilities

Some of the more useful utilities on the class side of `Filename` are shown below. The `isCaseSensitive` message tells you whether file names are case sensitive. For example, on Windows, there is no distinction between `'filename Ext'` and `'FILENAME.EXT'`. However, on Unix, these are very different files. The `defaultDirectory` message tells you the default directory you are in. The confusingly named `currentDirectory` tells you the relative directory name for constructing relative paths. The `volumes` message tells you what volumes are reachable. Finally, you can find all the files that match a specified pattern.

<table><tr><td>Filename isCaseSensitive.</td><td>false</td></tr><tr><td>Filename currentDirectory.</td><td>a FATFilename('.')</td></tr><tr><td>Filename defaultDirectory.</td><td>a FATFilename('c:\visual\image')</td></tr><tr><td>Filename volumes.</td><td>#{'A:\ 'B:\ 'C:\ 'D:\')</td></tr><tr><td>Filename filesMatching: '*.im'.</td><td>OrderedCollection ('visual.im' 'alec.im' 'math.im' 'mkim.im')</td></tr></table>

### Instance side utilities

#### Directories

If the instance of `Filename` is a directory, you can find its contents, or get all the files that match a certain wildcard pattern. For example,

```
dirName := Filename defaultDirectory.
dirName directoryContents.

# {'VISUAL.IM' 'VISUAL.SOU' 'VISUAL.CHA' 'ST' 'ALEC.IM' 'ALEC.CHA' 'SYSCHANG' 'MATH.IM' 'MKIM.IM' 'MYFILE' 'MKIM.CHA' 'GOODIES'}
dirName filesMatching: '*.im'

OrderedCollection ('c:\visual\image\visual.im'
```
'c:\visual\image\alec.im'
'c:\visual\image\math.im'
'c:\visual\image\mkim.im')

You can also create a directory by sending the `makeDirectory` message. Of course, this may fail if there is already a file with that name or the parent directory is unwritable. You can check for these conditions beforehand, or wrap the directory creation code with a signal handler.

## Contents of files

You can read the contents of a file into a string by sending `contentsOfEntireFile` (which closes the file after reading it). You can even bring up an editor on a file by sending `edit`.

## Information about files

You can find the various access and modification dates associated with a file by sending the `dates` message. You can check to see if a file exists by sending either `exists`, or `definitelyExists`, which handles inaccessible network files differently. The size of the file in bytes can be found by sending `fileSize`. You can determine if a file is readable or writable by sending `isReadable` and `isWritable` (for a directory to be writable, it must be possible to create and rename files in it). To find if the file is a true writeable file (ie, not a directory), send `canBeWritten`. If you want to know if a file is a directory, send `isDirectory`. You can tell if the file has an absolute or relative path by sending `isAbsolute` or `isRelative`. Let's look at some examples of these on a Windows machine.

<table><tr><td>dirName</td><td>::='c:\baseDir' asFilename.</td><td></td></tr><tr><td>filename</td><td>::= dirName construct: 'myfile'.</td><td></td></tr><tr><td>filename exists.</td><td></td><td>true</td></tr><tr><td>dirName definitelyExists.</td><td></td><td>true</td></tr><tr><td>filename fileSize.</td><td></td><td>20</td></tr><tr><td>dirName fileSize.</td><td></td><td>0</td></tr><tr><td>filename isReadable.</td><td></td><td>true</td></tr><tr><td>dirName isWritable.</td><td></td><td>true</td></tr><tr><td>filename canBeWritten.</td><td></td><td>true</td></tr><tr><td>dirName canBeWritten.</td><td></td><td>false</td></tr><tr><td>filename isDirectory.</td><td></td><td>false</td></tr><tr><td>dirName isDirectory.</td><td></td><td>true</td></tr><tr><td>filename isAbsolute.</td><td></td><td>true</td></tr><tr><td>dirName isRelative.</td><td></td><td>false</td></tr></table>

## Manipulating files

Among other utilities, you can delete a file (`delete`), you can copy a file to another file (`copyTo:`), and you can rename a file by moving it (`moveTo:`, which copies the file then deletes the original). If your platform supports it and it is a meaningful operation — for example, you are not trying to rename across disks — you can rename a file using the much more efficient `renameTo:` message.
15

Printing Objects

If you want to print information about an object, you send it the message `printString` and get back a string containing some information about the object. For example, `3 printString` returns '3'. `OrderedCollection new printString` returns 'OrderedCollection ()', which shows that you have an empty collection. Why is this useful? The `printString` message is used to display information for debugging. In particular, it is sent by inspectors; whenever you open an inspector on an object, the inspector sends the `printString` message to the object and displays the result.

The default `printString` is implemented by `Object`. It first creates a stream, then does `self printOn: stream`. `Object` also implements a default `printOn:` method that writes to the stream a string containing the class name preceded by 'a' or 'an'. If you create a new object, it will by default inherit `printOn:` from `Object`. Try the following. Define a new class `MyClass` then evaluate `MyClass new printString`.

If you want to change what `printString` returns, it's a simple matter of implementing `printOn:` (in the `printing` protocol). Take a look at the `printOn:` method for `Array`, `Association`, and `ValueHolder`.

Here's an example of a very general `printOn:`. It makes heavy use of meta-programming, which involves writing code that manipulates the information about such things as classes and instance variables. Not for the faint at heart, but it can be a lot of fun to look around classes such as `Behavior` and `ClassDescription`. For more on meta-programming, see Chapter 29, Meta-Programming.

```
printOn: aStream
super printOn: aStream.
self class allInstVarNames
do:
    [:each | | index |
        index := self class instVarIndexFor: each.
    aStream
crtab;
nextPutAll: each;
nextPut: $:
space;
print: (self instVarAt: index)]
```
I use this scheme in a slightly modified way. I write this method as `Object>>printAllOn:`, replacing the `super printOn: aStream` line with the code from `Object>>printOn:`. Then in my new classes, I write the `printOn:` method to simply invoke `printAllOn:`. Sometimes this doesn't give me the formatting I want so I'll write a specific `printOn:`, but often this will suffice.

```
MyClass>>printOn: aStream
super printAllOn: aStream
```

## Display strings

There is another message, `displayString`, which returns a value suitable for displaying. Where `printString` provides a representation of the object that is useful for debugging, `displayString` provides a representation that can be presented to the user. The default `displayString`, implemented by Object, just does `^self printString` but is overridden, for example, by `CharacterArray` (the superclass of String) so that strings do not have surrounding quotes. For example,

```
Transcript cr; show: 'Hello' printString. 'Hello'
Transcript cr; show: 'Hello' displayString. Hello
```

The `displayString` message is used when displaying objects in a List box. A List box has a SequenceView as its view, or widget. Its model is a `SelectionInList` containing the collection of objects. The widget displays what the objects return when sent `displayString`, although you can change this. To have a message different from `displayString` sent to the objects, send `displayStringSelector: aSymbol` to the List box widget (the SequenceView), passing as the parameter the message selector you want sent.

## Printing formatted numbers, dates, and times

Sending the `printString` message to a number returns the obvious representation of the number as a string. Sent to dates and times it returns a good representation, but in a pre-defined format. For example,

```
234 printString. '234'
Date today printString. '28 September 1995'
Time now printString. '9:59:04 am'
Timestamp now printString. '09/28/1995 09:59:29.000'
```

There are times when you want more. For example, when printing a number you might want commas to separate the thousands, parentheses to show a negative number, or to zero fill to a specified length. When specifying a date or a time you might have international formatting concerns. The `Date` class has an additional method called `printFormat`: that allows some, but not enough, flexibility. In the example below, we ask to print the month number, the day number and the two-digit year number, with the slash character as separator.

```
(Date newDay: 34 year: 1996) printFormat: #(2 1 3 $/ 1 2) '2/3/96'
```

The class `PrintConverter` lets you do some reasonably sophisticated formatting. You create a `PrintConverter` of the right type, specifying the format string you want, then you can ask the instance to format your numbers or dates when needed. Note that the `PrintConverter` returns an instance of `Text` so you'll need to send this the
string message to get a string. Let's look at some examples of formatting numbers, dates, and times. The string returned will be shown on the following lines.

```
pc := PrintConverter for: #number withFormatString: '00000'.
  (pc formatStringFor: 234) string.
  '00234'

pc := PrintConverter for: #date withFormatString: 'dddd, mmmm d,
yyyy'.
  (pc formatStringFor: Date today) string.
  'Thursday, September 28, 1995'

pc := PrintConverter for: #timestamp withFormatString: 'mmm d,
hh:mm:ss.ffff'.
  (pc formatStringFor: Timestamp now) string.
  'Sep 28, 09:55:48.0000'
```

The PrintConverter actually uses the classes `NumberPrintPolicy` and `TimestampPrintPolicy` to do the formatting. To understand all the formatting options, look at the class comments for these classes. You can also use these classes directly if you wish, and here are some examples of this. Again, the policy returns an instance of `Text`, which we convert to a string.

```
(NumberPrintPolicy print: 1234 using: '#,###') string.
  '1,234'
(NumberPrintPolicy print: -1234 using: '#,###;(#,###)') string.
  '(1,234)'
(TimestampPrintPolicy print: Date today using: 'yymmdd') string.
  '950928'
(TimestampPrintPolicy print: Time now using: 'mm:ss ff') string.
  '01:12.00'
```

There are more ways of using these classes than I've shown here. For example, you can write the formatted data to a stream, and you can create instances of the policy classes. The PrintConverter class also gives you an easier but less powerful interface for numbers. You can specify digit positions using `#`, so, for example, the following gives a string with two leading spaces.

```
PrintConverter print: 234 formattedBy: '#####.###'.
  ' 234.000'
```

## VisualWorks 2.5

VisualWorks 2.5 provides some extra formatting capabilities. In particular, dates and times now respond to the new messages `longPrintString` and `shortPrintString`. For example,

<table><tr><td>Date today printString.</td><td>'December 2, 1995'</td></tr><tr><td>Date today longPrintString.</td><td>'December 2, 1995'</td></tr><tr><td>Date today shortPrintString.</td><td>'12/2/95'</td></tr></table>

You can also create a string from a format string and arguments using a message from the `expandMacros` family in the class `CharacterArray`. For information on the parameter substitution, look at the class comments for `StringParameterSubstitution`. Here's an example, with the output following the example message. Note that the `expandMacrosWithArguments:` message returns an instance of `Text`, which we convert to a string.
```perl
('Hello <2s>.<n>There are <1p> <3?apples:oranges> in the basket'
expandMacrosWithArguments: #(4 'Alec' true)) asString.
```

'Hello Alec.'

There are 4 apples in the basket'

## printf-scanf

In the Smalltalk archives there is a fileIn called printf-scanf which gives you the capability of doing formatted printing as if you were using C's printf function. Its location in the MANCHESTER archive is usenet/st80-r4.X/printf-scanf. For more information on retrieving code from the Smalltalk archives, see Chapter 35, Public Domain Code and Information.
16
Processes

Smalltalk allows you to create separate processes so that your application can do several things in parallel. For example, you might have a process for handling communication with sockets, another process for handling communication with an external device, and separate processes for each request that comes over a socket. Note however, that processes are *not* operating system processes — they are internal to the Smalltalk image. There is a process scheduler which schedules the Smalltalk processes, allocating time based on their priority and when they last ran. The scheduler is stored in the global variable *Processor*, and is the single instance of the class *ProcessorScheduler*. The most common way to fork a new process is to send a block of code the *fork* message. For example,

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

When this process runs, it prints 'Hello World' to the Transcript. Once the right hand bracket of the block is reached, the process terminates. Let's look at the interactions of two processes.

[10 timesRepeat: [Transcript show: '1')] fork.
[10 timesRepeat: [Transcript show: '2')] fork.

1111111111222222222

You will see 10 1's printed on the Transcript then 10 2's. This is because processes are *partially preemptive*.
A running process will not be interrupted by another process of equal or lesser priority. A process will keep
running until it does a time consuming operation such as waiting on a socket read or on an instance of *Delay*, or
the process explicitly gives up control, or a higher priority process is ready to run. If we add a delay to both
loops we see that the numbers alternate.

[10 timesRepeat: [Transcript show: '1'. (Delay forMilliseconds: 1) wait]] fork.
[10 timesRepeat: [Transcript show: '2'. (Delay forMilliseconds: 1) wait]] fork.

121212121212121212
Alternatively, we can give up control by sending a `yield` message to `Processor`. The scheduler will then figure out the next process to run.

```
[10 timesRepeat: [Transcript show: '1'. Processor yield]] fork.
[10 timesRepeat: [Transcript show: '2'. Processor yield]] fork.
12121212121212121212
```

## Priority

When the process scheduler is looking for the next process to run, it looks first at the priority of the processes that are waiting to run. When you create a new process using `fork`, it inherits the priority of the process that forked it. However, you can specify the priority of the processes you create by sending the `forkAt:` message to the `BlockClosure`, with the priority as the parameter.

For example, if your application communicates with other applications via sockets, you might have one process sitting in an input loop, another process sitting in an output loop, and other processes doing the application work. You might run the application processes at one priority, the input process at a higher priority, and the output process at a still higher priority.

Let's look at how a higher priority process can preempt a lower priority process. We'll use absolute numbers rather than names for our priorities to make the examples clearer. VisualWorks supports priorities from 1 to 100, where the default priority is 50.

In the first example, we fork a process with priority 50. Since the user interface is also running at priority 50, the forked process is not interrupted, and therefore completes. The user interface then forks the second process, which also runs to completion. (The delay exists to make sure that the first process gets a chance to run. If we didn't have the delay, the user interface process would keep running and would fork the second process. At that point it would have nothing to do so the scheduler would look for another process to run, and would run the second process since it has higher priority.)

```
[10 timesRepeat: [Transcript show: '1')] forkAt: 50.
(Delay forMilliseconds: 1) wait.
[10 timesRepeat: [Transcript show: '2')] forkAt: 51.
1111111111222222222
```

In the second example, the first process is forked with a priority of 49, which is lower than the priority of the user interface process. The forked process just gets started and is then interrupted by the user interface process, which forks the second process. The second process is running at a higher priority than the first process, so it runs to completion. Then the first process gets the scheduler and completes.

```
[10 timesRepeat: [Transcript show: '1')] forkAt: 49.
(Delay forMilliseconds: 1) wait.
[10 timesRepeat: [Transcript show: '2')] forkAt: 51.
1122222222211111111
```

In the third example, the first process gives up control after printing the first number. The user interface then forks the second process, which gets to run since it has a higher priority. Even though the second process gives
up control after printing its first number, it is immediately run again because it is the highest priority process with something to do.

```
[10 timesRepeat: [Transcript show: '1'. Processor yield]] forkAt: 50.
(Delay forMilliseconds: 1) wait.
[10 timesRepeat: [Transcript show: '2'. Processor yield]] forkAt: 51.
122222222211111111
```

Smalltalk processes are *partially preemptive*. They can be interrupted by higher priority processes, but will *not* be interrupted by lower or equal priority processes. This is different to a multi-tasking system such as Unix, which gives timeslices to the different processes, interrupting them when they have consumed their timeslice. Since a Smalltalk process will not be interrupted by another process of equal or lower priority, it is easy to get into loops that you can't break out of. We'll look more at this in the section Working with Processes later in this chapter.

We used numbers in these examples, but a much better policy is to use the names defined in the `priority` names protocol of `ProcessorScheduler`, sending these messages to `Processor`. For example, at the time of writing, VisualWorks defines the following priorities.

<table><tr><td>systemRockBottomPriority</td><td>1</td></tr><tr><td>systemBackgroundPriority</td><td>10</td></tr><tr><td>userBackgroundPriority</td><td>30</td></tr><tr><td>userSchedulingPriority</td><td>50</td></tr><tr><td>userInterruptPriority</td><td>70</td></tr><tr><td>lowIOPriority</td><td>90</td></tr><tr><td>highIOPriority</td><td>98</td></tr><tr><td>timingPriority</td><td>100</td></tr></table>

Using names allows the values to be changed in future releases of the image without affecting your application. In fact, I'd go further and define my own names then fork the processes using my names.

```
My_globals class>>appProcessPriority
    ^Processor userSchedulingPriority
```
```
[some code] forkAt: My_globals appProcessPriority
```

Unless you have good reason, application process priorities should be kept in the range from `userBackgroundPriority` to `userInterruptPriority`.

## Communicating between Processes

In a production application, you will often find two types of process. One type of process is started, runs to completion, then automatically terminates. The other type of process stays in a loop waiting for an object to appear, then sends a message to the object. This requires an ability to communicate between processes, and Smalltalk provides such a mechanism, the *SharedQueue*.

### The SharedQueue

To set up communication between processes, you create an instance of `SharedQueue` and tell both processes about it. One process will put objects on the shared queue using `nextPut:` and the other process will send
`next` to get an object from the queue. When a process sends the `next` message, it blocks until there is something on the queue. (It blocks by waiting on a semaphore, which is set when an object is put on the SharedQueue. We'll talk more about semaphores in Chapter 17, Coordinating and Sequencing Events.) Figure 16-1 illustrates two processes communicating via a SharedQueue.

<figure><img src="image_15.png" /><figcaption>**Figure 16-1.** Using a SharedQueue.</figcaption></figure>

In the following example, the second process prints a number then puts it on a shared queue, while the first process reads the queue then prints the number. If you try this example, the Transcript will show: W1 R1 W2 R2 W3 R3 W4 R4 W5 R5.

```perl
sharedQueue := SharedQueue new.
readProcess := [[Transcript show: ' R', sharedQueue next printString]
repeat] fork.
[1 to: 5 do: [:index |
Transcript show: ' W', index printString.
sharedQueue nextPut: index.
Processor yield]] fork.
(Delay forSeconds: 5) wait.
readProcess terminate.
```

Notice that the read process will stay in a loop forever unless we terminate it. This we do with the `terminate` message (there is more on terminating processes in the next section). If you try this example again after removing the `Processor yield` in the second process, you will see: W1 W2 W3 W4 W5 R1 R2 R3 R4 R5. This is because Smalltalk is only partially preemptive and the first process doesn't get a chance to run until the second process is completed. I generally add `Processor yield` after putting an object on the SharedQueue, which ensures that the process waiting on the queue has a chance to run. For example,

```perl
sharedQueue nextPut: anObject.
Processor yield.
```

If the reading process doesn't want to block it can send ` empty ` to find out if there is anything on the SharedQueue, or ` peek ` to get the next object from the SharedQueue without removing it.

## The PrioritySharedQueue

SharedQueues are FIFO queues — objects are read from the queue in the order they were put on the queue. However, sometimes a simple FIFO queue is not sufficient because you might need a prioritization scheme. SharedQueues don't provide a mechanism for prioritizing objects on the queue, but you can subclass off
SharedQueue to create a PrioritySharedQueue. Here is a simple example of a PrioritySharedQueue, with an instance variable, *defaultPriority*. You can find the code for this example in the file `psq.st`.

```kotlin
PrioritySharedQueue>>defaultPriority: aPriority
    defaultPriority := aPriority

PrioritySharedQueue>>defaultPriority
    ^defaultPriority isNil
    ifTrue: [defaultPriority := 0]
    ifFalse: [defaultPriority]
```

A simple implementation puts all objects on the shared queue in an *Association* of the priority and the object. You will need to override `next`, `peek`, and `nextPut`: to handle the *Association*. Additionally, `nextPut`: will simply invoke `nextPut:priority`: as follows.

```kotlin
PrioritySharedQueue>>nextPut: anObject
    ^self nextPut: anObject priority: self defaultPriority
```

The heart of the PrioritySharedQueue is in the `nextPut:priority:` method, which places objects in the queue according to their priority first, and their chronology second. Higher numbers indicate higher priority.

```kotlin
PrioritySharedQueue>>nextPut: anObject priority: aPriority
[accessProtect critical:
    [ |foundElement |
        foundElement := contents
        reverseDetect: [:element | aPriority <= element key]
        ifNone: [nil].
        foundElement isNil
        ifTrue: [contents addFirst: (aPriority -> anObject)]
        ifFalse: [contents add: (aPriority -> anObject) after:
            foundElement]]
    ] valueUninterruptably.
readSynch signal.
^anObject
```

## A general SharedQueue reading mechanism

A general mechanism for taking objects off a SharedQueue and processing the objects is to sit in a loop like the following. This is very generic code and can easily be inherited. It has two specific virtues. First, it makes no assumptions about where the object is coming from and how it will be processed, so `myProcessObject:` and `myGetObject` can be overridden by subclasses to do things differently. Second, it allows you to put breakpoints in these two methods when you are debugging. Since `myDoLoop` is in a repeat loop, you can't add a breakpoint to this method while it is executing and have the breakpoint take effect.

```kotlin
MyClass>>myDoLoop
    [self myProcessObject: self myGetObject.
    Processor yield] repeat

MyClass>>myGetObject
    ^self mySharedQueue next.
```

We can extend this further for situations where we process the object in its own forked process. There are operations where it may be necessary to cancel the processing, such as time consuming operations or operations where a needed resource does not become available. If we need to cancel the processing, we can set an instance
variable in the object (protected by a mutual exclusion semaphore). At appropriate times during its processing, the object can look to see if it has been cancelled and take the appropriate action. In the code below, we store the object, then after the the object has executed the `processYourself` method, we remove the object from our collection. The `valueNowOrOnUnwindDo:` message ensures that the object is removed whether the `processYourself` method completes or is interrupted by a raised exception.

```kotlin
MyClass>>myProcessObject: anObject
self myAdd: anObject.
[[anObject processYourself]
valueNowOrOnUnwindDo:
[self myRemove: anObject]] fork
```

## Terminating processes

Processes terminate when they reach the right square bracket of the block that was forked. However, some processes are set up to stay in a loop, never reaching the right square bracket. We therefore need another way to terminate processes, which we get by sending the `terminate` message to the process. For example,

```kotlin
process := [[Transcript cr; show: 'Hi there'. (Delay forSeconds: 1)
wait] repeat] fork.
(Delay forSeconds: 5) wait.
process terminate.
Transcript cr; show: 'All Done'.
```

You can send `terminate` to an already terminated process with no ill-effects so `terminate` is a benign message. If you are concerned about terminating a process that is in the middle of doing something, you may want a way to shut down the process gracefully, allowing it to complete what it is working on. One option is to allow the process to terminate itself by sending `Processor terminateActive` or `Processor activeProcess terminate`. If the process reads from a `SharedQueue`, you can put a special termination object on the `SharedQueue`. If the `SharedQueue` reader does something like `sharedQueue next processYourself`, this special object would have the following code.

```kotlin
TerminationObject>>processYourself
Processor terminateActive
```

## Making shared data threadsafe

Objects running in different processes often require access to shared data. To make sure that only one process is reading or modifying the data, you need a mechanism to *序列化* access to the data. Smalltalk provides the *mutual exclusion semaphore* for just this situation. To create a mutual exclusion semaphore, you send the `forMutualExclusion` message to *Semaphore*. To serialize access to shared data, you ask the semaphore to run the access code. For example,

```kotlin
mutexSemaphore := Semaphore forMutualExclusion.
mutexSemaphore cricital: [code to access shared data]
```

We talk more about mutual exclusion semaphores in Chapter 17, Coordinating and Sequencing Events.
## Controlling the running of the process

In most applications you won't suspend and resume processes, but the ability is there should you need it. When you want to suspend a process, send it the `suspend` message. To resume the process, send it the `resume` message. You can start a process in suspended state by sending `newProcess` to a `BlockClosure`, and in fact, `fork` is implemented by sending `newRequest` followed by `resume`. Here's an example of creating a process that does not immediately run.

```kotlin
process := [Transcript cr; show: 'Done'] newProcess.
(Delay forSeconds: 3) wait.
process resume
```

If you decide to control the running of processes using `suspend` and `resume`, be very careful about when you suspend the process. It may be in the middle of doing something that should be completed before the process is suspended. One option is to have the process suspend itself when it is safe to do so. If you try the following code, you'll see that the process prints out the time five times, suspends itself, then is resumed five seconds later.

```kotlin
process :=
    [1 to: 10 do: [:index |
        Transcript cr; show: Time now printString.
        index = 5 ifTrue: [Processor activeProcess suspend]] fork.
    (Delay forSeconds: 5) wait.
process resume.
```

## Interrupting Processes

Smalltalk allows you to interrupt a process to have it do something else. You may never need to do this, but we'll mention the mechanism briefly. To interrupt another process and have it run some code, send `interruptWith: aBlockOfCode` to the process. The process saves its context, executes the passed-in block, restores its context, then resumes its business.

There is a way to prevent interruptions, in case the process is doing something it really doesn't want interrupted. You can protect the uninterruptable code by putting it in a block and sending the block the message `valueUninterruptably`. `SharedQueues` make use of this capability. All access to a `SharedQueue` is protected by a mutual exclusion semaphore. This access is wrapped in another block which is executed by sending `valueUninterruptably`. For example, `SharedQueue>>size` is implemented as `^[accessProtect critical: [contents size]] valueUninterruptably`. Will you ever use the interrupt capability? Probably not, but it's worth knowing about.

## Working with Processes

When you first work with processes, it's easy to write processes that stay in a tight loop so that you can't do anything. You can't even interrupt them with `ctrl-C` if they are running at `userSchedulingPriority` or above — ie, at or above the priority of the user interface process. For this reason it's always a good idea to file out (or save in some way) your changes before trying out new process code. It's also a good idea to run processes at a priority lower than `userSchedulingPriority`.

If you do get locked up, you can kill the virtual machine process or you can use the Emergency Evaluator. Unless you have remapped the interrupt key, pressing `Shift-Ctrl-C` will bring up the Emergency Evaluator.
From here you can type `ObjectMemory quit` followed by pressing the Escape key, which will cause Smalltalk to quit.

Another thing that can happen when working with forked processes is that you can lose them. Suppose you have a process running in a loop, possibly even yielding control. If you don't have a way to reference the process you can never terminate it. Here are some mechanisms for tracking processes.

## Tracking processes with a Global variable

One way to track your processes is to keep each process in a global variable. Let's say you choose to keep track of global variables in class `MyGlobs`. If you have a class variable called `Processes` that you initialize to an `OrderedCollection` (using class initialization or lazy initialization), you can have two methods:

```myobject
MyGlobs class>>addProcess: aProcess
    ^Processes add: aProcess

MyGlobs class>>removeProcess: aProcess
    ^Processes remove: aProcess ifAbsent: [nil]
```

At any time you can inspect `MyGlobs` to see a collection of all the processes you have forked. You can terminate them individually or create a method to terminate all of them. To better know what process you are looking at, you could add an Association of the process and a name.

```myobject
MyGlobs class>>addProcess: aProcess name: aName
    ^Processes add: aProcess -> aName

MyGlobs class>>removeProcess: aProcess
    ^Processes removeAllSuchThat: [:each | each key = aProcess]
```

This scheme assumes that the forked processes you add can also be removed. Many processes are simply short-lived process that terminate naturally and there will be no easy way to remove them from the collection (unless they remove themselves before expiring). This scheme works best with long-lived processes that the application can both start and terminate.

## Tracking processes by subclassing

Another approach is to create your own process class, say `MyProcess`, as a subclass of `Process` (you can find the code in the file `process.st`). We'll give it an instance variable to store the process name.

```myobject
Process subclass: #MyProcess
    instanceVariableNames: 'processName '
    classVariableNames: ''
    poolDictionaries: ''
    category: 'MyStuff'
```

Add `processName` and `processName: accessors`, and write a `printOn:` method.

```myobject
MyProcess>>printOn: aStream
    super printOn: aStream.
    aStream nextPutAll: ' ('.
    aStream nextPutAll: self processName.
    aStream nextPut: $)
```
Without going into all the details, this involves writing three new methods for `BlockClosure`. The first method is `newProcessWithName:`, which creates an instance of `MyProcess` rather than `Process`, and sets the process name. The other two methods are `forkWithName:` and `forkAt:withName:` which send `newProcessWithName:` rather than `newProcess`. You will then need to add an `allInstancesAndSubInstances` method to `Behavior` (we show this method in Chapter 29, Meta-Programming). Once you have this, the final change is to modify `Process>>anyProcessesAbove:` to send `allInstancesAndSubInstances` rather than `allInstances`. You can now fork all your processes by doing:

```
[some code] forkWithName: 'some name'.
```

If you then inspect `MyProcess allInstances`, you can take a look at all your processes that are running (or which have terminated but not been garbage collected). To terminate a lost process, you can open an inspector on the appropriate element of the array then evaluate `self terminate` in the inspector window.

To handle the problem of a process locking up the image, you can write a class side method to terminate all instances of `MyProcess`. From the Emergency Evaluator (`Shift-Ctrl-C`), you can now type `MyProcess terminateAll` followed by Esc, and you should get back your cursor.

```ruby
MyProcess class>>terminateAll
self allInstances do:
  [:each |
    Transcript cr; show: each printString.
    each terminate]
```

It may be easier to modify `Process` rather than subclass off it. If you choose this approach, you would add a `processName` instance variable. You will still need to add fork-type methods to `BlockClosure` to set the process name before sending resume to the process. Finally, instead of `MyProcess class>>terminateAll`, you might write something like the following.

```ruby
Process class>>terminateNamed
self allInstances do:
  [:each | each processName notNil ifTrue:
    [Transcript cr; show: each printString.
    each terminate]]
```
# 17

## Coordinating and Sequencing events

When you program an application where many things happen at the same time in different threads or processes, you have to concern yourself with access to shared resources. You have to program some amount of event coordination.

### Regular semaphores

Semaphores allow you to wait for a resource to become available or to change state before you continue processing. One example might be an object that needs a certain event to happen, such as a door to be opened or a button to be pressed. One solution would be to wait on a semaphore that gets signaled by a process monitoring the door or button. Another example might be a tape drive that is shared among several processes that want to mount and dismount tapes. We could use a semaphore to coordinate and serialize the events.

<figure><img src="image_16.png" /><figcaption>**Figure 17-1.**
The Semaphore mechanism.</figcaption></figure>

To use a semaphore, you first create an instance of *Semaphore* by sending it the *new* message. A process waits on the semaphore by sending it the *wait* message. This suspends the process until another process signals the
semaphore by sending it the *signal* message. The semaphore will then resume the suspended process that is waiting on it. Figure 17-1 illustrates this. Here's a simple example of waiting on a Semaphore.

```
semaphore := Semaphore new.

[Transcript cr; show: 'About to wait'.
semaphore wait.
Transcript cr; show: 'Semaphore signaled'] fork.

[(Delay forSeconds: 5) wait.
semaphore signal] fork.
```

In our tape example, the tape drive object has a semaphore. When a tape wants to be mounted in a drive, the tape waits on the drive's semaphore. When the drive becomes available, it signals its semaphore, which allows the tape to continue mounting itself. Semaphores have the additional virtue of queuing `wait` requests in the order they were received so that we could have many tapes waiting for the drive. As the drive becomes available and signals its semaphore, the first tape in the queue will mount itself, while the other tape processes remain suspended until the drive becomes available and it is their turn.

```
Tape>>mountYourselfOn: aDrive
    self doSomeMountStuff.
    aDrive reserve.
    self doMoreMountStuff

Tape>>dismountYourselfFrom: aDrive
    self doSomeDismountStuff.
    aDrive release.
    self doSomeMoreDismountStuff

Drive>>reserve
    semaphore wait

Drive>>release
    semaphore signal
```

Besides queueing up `wait` requests by sending multiple `wait` messages to a semaphore, you can also prime a semaphore by sending multiple `signal` messages. This could be useful if you are using a semaphore to control access to a resource that allows several accesses at once. By sending several `signal` messages to the semaphore when it is created, you allow the first few objects access to the resource. As they release the resource, they signal the semaphore, allowing the next object to get access.

## Mutual exclusion semaphores

Sometimes you want to serialize access to shared data. A good example is tracking the state of a resource that is being modified by different processes. The state data needs to be read and written, but we need to make sure that we don't have different processes trying to access it at the same time. (In fact, since Smalltalk is only partially preemptive, this will probably not be a problem, but it's better to be defensive in our programming.) Another
example is reserving a resource, where we want to first check the state of the resource and then reserve it if it is
available. We want the checking and reserving to be an atomic operation, without the possibility of interruption.

<figure><img src="image_17.png" /><figcaption>**Figure 17-2.**
Mutual Exclusion Semaphore.</figcaption></figure>

We use a special type of semaphore called a *mutual exclusion semaphore*, which runs a block of code when sent the `critical:` message. A mutual exclusion semaphore will only run one block of code at a time. This is illustrated in Figure 17-2. As long as all our data access routines are run by the mutual exclusion semaphore, we are guaranteed that the data will be only be accessed by one routine at a time. Here's an example of how we might use a mutual exclusion semaphore to protect a shared resource.

```cpp
MyClass class>>initialize
    AccessProtect := Semaphore forMutualExclusion.

MyClass>>stateData
    ^AccessProtect critical: [code to get the value]

MyClass>>stateData: aValue
    AccessProtect critical: [code to set the value]
```

We ask the mutual exclusion semaphore to run the code critically. The semaphore will run only one block of code at a time, queuing up the other blocks in the order it was asked to run them.

A mutual exclusion semaphore works by immediately signaling itself when it is created. This allows the first block of code to run without waiting (it tries to wait, but since the semaphore has already been signalled, no waiting is needed). Once the block has been executed in the `critical:` method, the method signals the semaphore again. If there is another block of code waiting, it will now run. If there is no code waiting to be run, the semaphore is primed so that the next block to come along will run without waiting. (The code block is run by sending `valueNowOrOnUnwindDo: [self signal]` to the BlockClosure. This causes the code block to be run, and then `self signal` to be executed no matter whether the block runs to completion, returns, or is interrupted by an exception.)

Here's an example of a mutual exclusion semaphore that you can run in a Workspace. It protects access to the Transcript, which in fact is a reasonable thing to do since the Transcript is not threadsafe.

```cpp
accessProtect := Semaphore forMutualExclusion.

[accessProtect critical:
    [Transcript cr; show: 'Process1 ', Time now printString.
```
(Delay forSeconds: 5) wait]] fork.

[accessProtect critical:
[Transcript cr; show: 'Process2 ', Time now printString]] fork.

An important point to note is that to protect access to shared data, the processes must cooperate. If one process asks a mutual exclusion semaphore to control its access to the data, but another process goes directly to the data, that data is no longer threadsafe. Ideally, your shared data will only be accessible through access routines which all cooperate and use a mutual exclusion semaphore.

RecursionLock

Sometimes we may find ourselves in a situation where a mutual exclusion semaphore is executing code in a
critical block, and the code needs access to another resource that is protected by the same semaphore.

If we use a mutual exclusion semaphore our code will hang because the semaphore is already running code. To solve the problem we use a *RecursionLock* rather than a mutual exclusion semaphore. A *RecursionLock* knows which process is running, and allows additional access by that process to resources it is protecting.

Summary

To summarize, use a regular semaphore (Semaphore new) to coordinate events such as waiting for a button to be pressed. Use a mutual exclusion semaphore (Semaphore forMutualExclusion) to serialize access to resources such as data stores. Use a RecursionLock (RecursionLock new) instead of a mutual exclusion semaphore when the code that accesses the resource may need to access another resource protected by the same semaphore.
Copyright © 1997 by Alec Sharp

Download more free Smalltalk-Books at:

- The University of Berne: http://www.iam.unibe.ch/~ducasse/WebPages/FreeBooks.html

- European Smalltalk Users Group: http://www.esug.org
18

Cleaning up at Termination

Having a garbage collector to take care of memory management for you is wonderful. Not having to worry
about allocating and freeing memory makes life a lot easier and code a lot more bug-free. However, there are
some things that the garbage collector does not take care of, and which you need to explicitly handle in the code.

In particular, external resources will stay open even if the objects that reference them are garbage collected.
For example, if you open a file or a socket, it will stay open until you close it (or your Smalltalk image exits).
Internally, if you have a Smalltalk process that stays in an infinite loop waiting for input to process, that process
will never terminate, even if you no longer reference the process in your code.

Often you will open files, read or write them, then close them. Similarly, often you will fork Smalltalk processes that do some work then simply terminate. However, on other occasions you may open a file that you plan on keeping open for a while, such as a log file. You may have a Smalltalk process that sits in an infinite loop waiting for input from a socket or waiting for input from another Smalltalk process.

Exiting your image will close external files and sockets and terminate Smalltalk processes. However, when
you are developing and debugging an application, bugs in your code will often raise an exception which you try
to debug, then eventually terminate. This leaves processes running and files open. This chapter talks a little about
how you might close files and terminate processes when you terminate the application in situations like this. For
more information, see the article *Cleaning up after yourself*, by Alec Sharp and Dave Farmer, in the March-
April, 1995 issue of The Smalltalk Report.

The CleanUp object

We define a new class called *CleanUp*, which tracks, for example, the sockets, files and Smalltalk processes that are permanently open. We don't add files that are opened, read, and then closed in a *valueNowOrOnUnwindDo*: block. Here's the definition of *CleanUp*, followed by the class initialization and instance creation code. This code can also be found in the file *cleanup.st*.

Object subclass: #CleanUp
instanceVariableNames: 'processes files sockets '
classVariableNames: 'AccessProtect '
poolDictionaries: ''

Copyright © 1997 by Alec Sharp
category: 'CleanUp'

CleanUp class>>initialize
  "self initialize"
  AccessProtect := Semaphore forMutualExclusion

CleanUp class>>new
  ^super new initialize

We create the mutual exclusion semaphore because our application may be running in many forked processes. To make sure that only one process is trying to add to the CleanUp object at a time, we use the semaphore to protect access to the various collections. On the instance side, we initialize the variables that hold on to the files, sockets, and processes, and we provide methods to add files, processes, and sockets to the CleanUp object. We also need methods to remove them from the object should the application code close them itself. We'll just show the code that adds files, since the code for processes and sockets is very similar.

CleanUp>>initialize
  processes := OrderedCollection new.
  files := OrderedCollection new.
  sockets := OrderedCollection new

CleanUp>>addFile: aFile
  ^AccessProtect critical: [files add: aFile]

CleanUp>>removeFile: aFile
  ^AccessProtect critical: [files remove: aFile]

When the application terminates, we want to close all the open files and sockets, and terminate all the processes. We nil the instance variables at the end so the garbage collector can recover the objects that were contained in the collections (we assume that a new CleanUp object will be created next time the application is run).

CleanUp>>doCleanUp
AccessProtect
critical:
  [processes do: [:each | each terminate].
  files do: [:each | each close].
  sockets do: [:each | each close].
  processes := files := sockets := nil]

## Using the CleanUp object

Now that we have a CleanUp class defined, how do we use it in our application. The first decision is where to store it so that it is globally accessible. There's a lot more information on that topic in Chapter 7, Global Variables. For now, we'll just assume that it's stored in the class *My_globals* and is accessible through the *cleanUp* accessor. The next section of code shows (in a non-robust way) how we might add files, sockets, and processes to the CleanUp object in our code.

MyClass>>myStartInputOutput
  My_globals cleanUp addSocket: self myCreateInputSocket.
  My_globals cleanUp addSocket: self myCreateOutputSocket.
  My_globals cleanUp addProcess: [self myDoInputLoop] fork.
  My_globals cleanUp addProcess: [self myDoOutputLoop] fork.
```python
MyClass>>myOpenLogFile
    logFile := self logFileName writeStream.
    My_globals cleanUp addFile: logFile
```

Finally, we need code to invoke the `cleanUp` message to the `CleanUp` object so that all files and sockets are closed and all processes are terminated. We do this by wrapping our main application start code in a `valueNowOrOnUnwindDo:` block. This makes sure that clean up is done whether the application terminated normally, we interrupted the application with `ctrl-C`, or we got an exception.

```python
MyApplication>> start
    [self myStartInputOutput.
     [self myProcessObject: self myObject] repeat]
    valueNowOrOnUnwindDo: [My_globals cleanUp doCleanUp]
```

## Other approaches

There are of course other approaches to the problem of making sure that you close and terminate everything that is open and running. The technique described in this chapter is a fairly easy and expedient technique. As you move toward a production system, a better and more object-oriented approach is to spread the responsibility to each subsystem or component. Each subsystem tracks what it has open or running. When the main application is shut down, it sends a `shutdown` message to each subsystem. The subsystem then shuts itself down gracefully, closing files, terminating processes, and doing any other appropriate operations.
19

The Dependency Mechanism

Perhaps the most magical thing about Smalltalk is the way it can automatically inform objects when other
objects change their state. It does this by allowing one object to register an interest in getting change messages
— by registering as a *dependent* of another object. The terminology is that the object registering an interest in
being informed of changes is called the *dependent*. The object that it is dependent on is called the *parent*.

Being able to use the dependency mechanism allows you to write code where an object registers as a
dependent then forgets about the parent completely. When the parent changes, the object will be informed and
can do whatever it needs to do but until that time, it can forget the parent even exists. From the perspective of the
parent, there is no need to programatically keep track of all the objects it needs to inform of changes. Instead, all
you have to do is have the parent tell itself that it has changed, and all the dependents will be automatically
notified. The dependency mechanism allows you to think of an application as a group of objects with wiring
between them. A major part of the application now boils down to determining the wiring between the objects.

How is this useful? There are many applications where one object is interested in the state of another object,
but the second object really doesn't care about the first object. It doesn't care whether there are many objects
interested in it, or no objects interested in it. One example would be a stock object that holds onto its current
trading price. There may be many applications interested in the price of the stock as it changes, but the stock
really doesn't care about those applications. Another example would be a factory floor. There may be many
monitors interested in the temperature and quantity of a liquid in a container, but the container has no interest in
the monitors. However, in the examples, the stock and the container have to let other objects know about
changes in their state.

There are two mechanisms for doing this. The interested objects could *poll* the stock and container objects, asking for their state every few seconds. However, this has disadvantages. It takes computer resources to constantly ask for information and this can add up if there are lots of objects polling. It also means that objects aren't informed of changes in real-time. If an object polls every five seconds, it could be five seconds before it discovers a state change, which could be disastrous on a factory floor. If it polls every hundredth of a second, huge amounts of computing bandwidth will be used if you have many objects polling.

The other approach is to use the dependency mechanism. The interested objects register an interest in some
aspect of the stock or container's state, then wait until they are informed of changes. The stock or container
doesn't know or care how many interested objects there are. Let's go through an example and see how the
dependency mechanism works.

We'll look at a simple example of a stock object and a watcher object that is monitoring the *stock price*. As a stock is traded, the stock object gets updated with the latest price and the number of shares in the trade. Since we don't know how many stock watchers will be monitoring any particular stock, and we don't know what they will do with the values, we don't want the stock to be responsible for who to tell, and what to tell them. Instead, we use the dependency mechanism. When the stock receives information about a new trade, it updates its instance variables. When it updates an instance variable, it tells itself that it has done so. This act of telling itself that it has changed triggers off the whole dependency notification mechanism.

We'll be showing several mechanisms and each example will be suffixed with a number. To execute the
example, type the following into a workspace, highlight it, and evaluate it (don't do it yet since we haven't yet
defined any classes and methods). Make sure that the number is appropriate for the example. The code for all
these examples can be found in the file depend.st.

| stock |
stock := MyStock1 new.
MyStockWatcher1 watchStock: stock.
stock traded: 200 price: 20.
stock traded: 100 price: 30

Basic Dependency

Here are the class definition and the instance methods for the stock class. Notice that instance variables are changed through their accessors, and their accessors are responsible for telling the stock object what has changed, and the old value. This is the key part of the parent's role in the dependency mechanism. By sending `changed:with:`, a whole set of dependency code is invoked. The normal convention is to send the *old* value since the dependent can send a message to get the new value, and may otherwise not know the old value. Sometimes, however, you will see the new value sent. Whichever approach you take, be consistent.

Most of the methods of the stocks are defined in the superclass, *MyStock*. Where necessary we will override this behavior. The accessor methods look very similar for each variable, so we'll write them just for *price*. The other accessors will simply have different names for the variables.

Model subclass: #MyStock
instanceVariableNames: 'price trade totalTraded '
classVariableNames: ''
poolDictionaries: ''
category: 'DependencyTests'

MyStock>>traded: aCount price: aPrice
self price: aPrice.
self trade: aCount.
self totalTraded: self totalTraded + aCount

MyStock>>price
^price isNil
    ifTrue: [price := 0]
    ifFalse: [price]

MyStock>>price: aPrice
| oldPrice |
oldPrice := self price.
price := aPrice.
self changed: #price with: oldPrice

The stock watcher adds itself as a dependent of the stock (the parent) when it is created. To do this it simply sends the stock an `addDependent:` message with itself as the parameter. Note that all the examples have the same `watchStock:` method so we will define it in the superclass, `MyStockWatcher`. The stock watcher has no instance variables so we are not showing the class definition.

MyStockWatcher class>>watchStock: aStock
    ^super new initialize: aStock

MyStockWatcher1>>initialize: aStock
    aStock addDependent: self

MyStockWatcher1>> update: aSymbol with: oldPrice from: aStock
Transcript cr; print: thisContext; tab; print: aSymbol; tab.
aSymbol == #price ifTrue:
    [Transcript
        nextPutAll: 'Price changed from: '; print: oldPrice;
        nextPutAll: ' to '; print: aStock price].
Transcript flush.

We'll see the details of how this works in the next section, but briefly, the stock watcher is informed of all the changes and has to decide if the change is one that it is interested in. Since our stock watcher is only monitoring the price, it ignores all the other changes. If you run this code, you'll see that it is informed of several different changes, but only reports on the price change.

## Underlying mechanism

There are some very sophisticated mechanisms that allow dependency to work but they all rely on the very basic mechanism of the parent sending itself a message from the `changed` family and the dependent being sent a message from the `update` family.

The dependency mechanism is implemented by `Object`, which means that any object can register itself as a dependent of any other object. When the parent changes, the most primitive mechanism for letting others know is to send itself `self changed`. This method is implemented by `Object` so let's see what it does.

Object>>changed
    self changed: nil

Object>>changed: anAspectSymbol
    self changed: anAspectSymbol with: nil

Object>>changed: anAspectSymbol with: aParameter
    self myDependents
        update: anAspectSymbol
        with: aParameter
        from: self

As you see, if your object simply sends the `changed` message, this becomes transformed into a `changed:with:` message with both parameters being `nil`. Usually you will provide more information by sending either the `changed:` or `changed:with:` message. If you want to inform your dependents what
changed, send changed: and pass a symbol as the parameter. When the dependent gets an update message, it
will be able to look at the symbol and decide if it is interested in the change. If you want to go further, send the
changed:with: message, passing the symbol and either the old or new value as parameters. This is what we
did in our stock watcher example, sending the old value.

(There are two conventions worth knowing about. First, it's possible to send anything as the argument to changed:. However, by convention, most people send a symbol, the symbol being the selector that is used to retrieve the new value. Second, the usual convention is to send the old value in changed:with:, on the assumption that the dependents may no longer know the old value, but they can always get the new value by asking the parent. However, some people prefer to send the new value since there is less message sending involved. They take the approach that if any dependent cares about the old value they can store it, Whichever approach you take — sending the old value or the new value — make sure you do the same thing everywhere so that other programmers can rely on getting what they expect.)

Eventually the parent sends all its dependents the update:with:from: message, so the dependents must implement one of the update family of messages. What if you don't care about all the parameters of update:with:from:?: Just as Object expanded changed up to changed:with:, it contracts update:with:from: down to update.

Object>>update: anAspectSymbol with: aParameter from: Sender
^self update: anAspectSymbol with: aParameter

Object>>update: anAspectSymbol with: aParameter
^self update: anAspectSymbol

Object>>update: anAspectSymbol
^self

Your dependent object thus has a choice of which of the three messages in the update family to override.
Once you've implemented it, your method will be invoked rather than Object's method, since you are overriding
Object's implementation. If you don't implement any update method, the results will be benign and you won't
even notice that anything happened. In our example, we implemented update:with:from:. Figure 19-1
illustrates our example.

<figure><img src="image_18.png" /><figcaption>**Figure 19-1.**
The addDependent: mechanism.</figcaption></figure>

Model

In the changed:with: method, Object sends the myDependents message to get a collection of dependents. Object has a class variable, *DependentsFields*, which is a Dictionary indexed by objects that have dependents. The general access mechanism is DependentsFields at: objectWithDependents put: collectionOfDependents.
The main problem with this scheme is that if an object doesn't remove itself as a dependent by sending its parent `removeDependent: self`, the dependents collection will never disappear from Object's class variable. (You can see if you are cluttering up this collection by inspecting Object's `DependentsFields` class variable.) Since the dependent objects continue to be referenced, they will not be garbage collected even though they are no longer needed. What we'd like is a mechanism that automatically gets rid of the dependency relationship when the parent is garbage collected, allowing the dependents to also be garbage collected when they are no longer needed.

This is where the class *Model* comes in. It is a subclass of Object, and has a single instance variable called *dependents*. An instance of Model keeps its dependents in a collection held by the *dependents* instance variable. This means that if the instance is garbage collected, the dependents collection will disappear even though dependents never send the `removeDependent:` message (however, it's good practice to always send `removeDependent:`). If you look back to example one, you'll notice that our stock class is subclassed off Model.

If you don't fully understand this, it doesn't matter. Just remember the basic rule: If you are going to use dependencies a lot, subclass your parent class off Model rather than off Object.

## `expressInterestIn:for:sendBack`:

Notice that the `update:with:from:` method in Example One has to compare the symbol it receives with all the possible symbols it cares about (in effect doing a switch statement). The basic dependency mechanism suffers from the disadvantage that *all* dependents are sent *all* changed messages, even if they are not interested in most of them. Dependents must implement one of the `update` family of messages and must check to see if they are interested in the particular symbol that was sent.

We can eliminate the conditional checking that we saw in the update method by sending `expressInterestIn:for:sendBack:` instead of `addDependent:` to the parent object. In this approach, we tell the parent to express an interest in a particular change for us and send us a specified message when it sees the symbol associated with the change (i.e., the symbol sent by the parent when that particular thing changes). The syntax is confusing because you would expect the dependent to express interest in the parent. However, the syntax is such that the dependent tells the parent to express an interest in the dependent. Let's look at an example using this approach.

```ruby
MyStockWatcher2>>initialize: aStock
aStock
    expressInterestIn: #price
    for: self
    sendBack: #priceChanged:by:

MyStockWatcher2>>priceChanged: oldPrice by: aStock
Transcript
    cr; print: thisContext; tab;
    nextPutAll: 'Price changed from: '; print: oldPrice;
    nextPutAll: ' to '; print: aStock price; flush
```

So how does this work? Rather than asking the parent to send us all changed messages and then filtering them out, we ask the parent to do the filtering, sending us a different message for each change we are interested in. If the message we asked to be sent has no parameters, we will just be sent the message. If the message has
one parameter (binary message or keyword message with one colon), we will be sent the old value as the parameter. If the message has two colons, as does our example, we will be sent the old value and the object that changed.

If you are interested in how this is done, the parent creates a *DependencyTransformer* and adds the *DependencyTransformer* as a dependent. The *DependencyTransformer* gets all the update messages and looks for the one we have expressed interest in. When it sees the change we care about, it sends us the message that we registered as the parameter to the `sendBack:` keyword. The *DependencyTransformer* is very clever when it comes to sending us the message. When we expressed interest in changes, the *DependencyTransformer* figured out how many parameters our message expects based on whether it is a binary message or how many colons are in the message. It implements `update:with:from:` so that it knows what changed, the old value, and the object that sent itself the changed message, and it sends us the appropriate number of parameters. Of course, if the parent didn't send `changed:with:`, one or more of the arguments will be `nil`. Figure 19-2 illustrates this mechanism.

<figure><img src="image_19.png" /><figcaption>**Figure 19-2.** The `addDependent:` mechanism.</figcaption></figure>

Finally, to stop being told about changes, the dependent has to retract interest in that particular change of the parent. It does so by sending the `retractInterestIn:for:` message, which should always be done. For example,

`parent retractInterestIn: #number for: self`

### ChangeSend:to:

Hiding the complexity further is the `onChangeSend:to:` message, which is implemented by the abstract class *ValueModel*. It takes two parameters: the message that should be sent, and the object to send it to. Notice that we don't specify what change we are interested in. This is because a *ValueModel* handles both the expression of interest in changes, and the notification of changes, so it can make certain decisions for us. All that `onChangeSend:to:` does is express an interest in the symbol `#value`.

``` FLASH
ValueModel>>onChangeSend: aSymbol to: anObject
self
    expressInterestIn: #value
    for: anObject
    sendBack: aSymbol
```
So what is a ValueModel? It is basically a wrapper around a value — it holds the value. We can't change the value directly and can only change it through the ValueModel. Because the ValueModel has control of the change, it can notify dependents of the change. To set a new value, you send the ValueModel the `value:` message with the new value as a parameter, and `value:` simply sets the value and notifies any dependents by doing `self changed: #value`.

```python
ValueModel>>value: newValue
self setValue: newValue.
self changed: #value
```

Because `onChangeSend/to:` translates into `expressInterestIn:for:sendBack:` and this latter message creates a DependencyTransformer, we now have a DependencyTransformer waiting for its parent to send `self changed: #value`. Once it receives this, it will send back the message we registered. ValueModel and its subclasses are widely used in the User Interface widgets.

Let's look at our third example, which uses instances of `ValueHolder`, the simplest subclass of ValueModel. In this example the `get` accessors return a `ValueHolder` (sending the `asValue` message to an object returns a `ValueHolder` holding the object). The `set` accessors go through a level of indirection because they can't set the value directly; they have to ask the `ValueHolder` to set it. So they send the `value:` message to the `ValueHolder`, which updates the value it is holding and informs itself about the change. Unlike the previous two examples, which inform their dependents of the old value, the `ValueHolder` mechanism provides no ability to do this. Figure 19-3 illustrates this mechanism.

<figure><img src="image_20.png" /><figcaption>**Figure 19-3.** The `addDependent:` mechanism.</figcaption></figure>

In the example we'll just show the accessors for `price` since the other accessors have the same structure, just different variable names. Additionally, the `traded:price:` message knows that we are dealing with a `ValueHolder`, so it sends the `value` message to get the current value of `totalTraded`.

```python
MyStock3>>traded: aCount price: aPrice
         self totalTraded: self totalTraded value + aCount.
         self price: aPrice

MyStock3>>price
    ^price isNil
        ifTrue: [price := 0 asValue]
        ifFalse: [price]
```
```kotlin
MyStock3>>price: aValue
self price value: aValue
```

If you look at the following stock watcher methods, you'll notice that we have an instance variable, `stock`, which we need to add to the class definition for `MyStockWatcher3`. Because `ValueHolders` do `self changed: #value` rather than sending the `changed:with:` message, they don't pass back a value. When our `StockWatcher` discovers that the price has changed, it needs to send the stock a message to find out the new price. To do this, it needs to keep hold of the stock in an instance variable. Also, because no value is passed, we don't have a way to track the old value unless we were to keep it in an instance variable.

```kotlin
MyStockWatcher3>>initialize: aStock
stock := aStock.
stock price ONChangeSend: #priceChanged to: self

MyStockWatcher3>>priceChanged
Transcript
    cr; print: thisContext; tab;
    nextPutAll: 'New price='; print: stock price value;
    flush
```

We could dispense with the instance variable if we are prepared to specify a two keyword message where we know the parameter to the first keyword will be `nil`. So we might write the above two methods as follows.

```kotlin
MyStockWatcher3>>initialize: aStock
aStock price ONChangeSend: #priceChanged:by: to: self

MyStockWatcher3>>priceChanged: aPlaceHolder by: aStock
Transcript
    cr; print: thisContext; tab;
    nextPutAll: 'New price='; print: aStock value;
    flush
```

To cancel the dependency we set up with `ONChangeSend:to:`, we send the `retractInterestIn:for:` message. For example,

`parent retractInterestIn: #priceChanged for: self`

## Which mechanism should you use?

Some people use `ONChangeSend:to:` for basic dependencies since it is an elegant message. However, for general dependencies the `ValueHolder` mechanism suffers from some disadvantages. To register as a dependent, an object must send `ONChangeSend:to:` to a `ValueHolder`. This means that the parent object, which may be an instance variable, must hold a wrapper rather than real data, which is conceptually inelegant. A more serious disadvantage is that for objects to register an interest in a variable, you have to open up the details of the object. The data is no longer fully encapsulated in the sense that other objects now know how the data is stored.

With either the `expressInterestIn:for:sendBack:` or the `addDependent:` mechanism, the parents are free to change the way they store and manipulate their data, as long as they still notify themselves of changes with the same symbol.

`ValueHolders` and other subclasses of `ValueModel` are widely used in the User Interface widgets and you'll see a lot more of them in Chapter 23, Model-View-Controller, and Chapter 24, MVC Dependencies. However,
for basic dependencies, I prefer the other mechanisms: `expressInterestIn:for:sendBack:` and `addDependent:`. Of the two, my preference is for `expressInterestIn:for:sendBack:`. With the `addDependent:` mechanism you have a single method that receives notification of all changes to all parents. It's now up to your method to make sense of all the notifications, which can result in a very procedural-looking set of `booleanCondition ifTrue:` statements. On the other hand, `expressInterestIn:for:sendBack:` allows you a narrower focus on the specific problem. When a particular aspect of the parent changes, send me a particular message. When another aspect in a different parent changes, send me a different message. It's a nice object-oriented approach.

## Broadcasting

VisualWorks provides the ability for a parent to broadcast a message to all its dependents. In our stock example, there may be cause for concern if a stock price changes more than thirty percent in a single trade. Who's responsibility is it to care about this? A good argument can be made that the stock itself doesn't care and that it's the responsibility of the stock watchers to handle the situation. For the sake of this discussion, however, let's make the case the stock cares that its price has risen more than twenty percent, and that it needs to inform its dependents.

The broadcast mechanism lets it do that. There are two messages, `broadcast:` `aMessage` and `broadcast:` `aMessage` with: `aParameter`. Since the stock watchers need to know which stock is sending the message, it makes more sense to use the second message. So, we might see code in the `traded:price:` method in `Stock` to do something like the following:

```myStock traded: aCount price: aPrice
... code to set values ...
price notNil ifTrue:
    [(aPrice - price / price) abs > 0.3
        ifTrue: [self broadcast: #bigChange: with: self]]
```

This unilaterally sends the `bigChange:` message to all dependents passing the stock object as the parameter. If the dependents haven't implemented `bigChange:`, an exception will be raised. So there's a responsibility on the dependents to implement this message, even if they don't care about large changes in price. There's also an argument against specifically broadcasting a large change in price since one might argue that the responsibility of stock is simply to inform its dependents about changes in price. It's the responsibility of the dependents to decide if a given change is too high.

In the dependency scheme, the general philosophy is that dependents know about and care about the parent, but the parent doesn't know or care about the dependents. This philosophy breaks down with broadcasting because if the parent decides to send a new message, some programmer has to figure out all the objects that register as dependents, then add the new message to each of them. An alternative and better approach would be to modify the broadcast messages to do safe performs (look for implementors of `safelyPerform:` to see how this is done).

If you modify `traded:price:` to include the broadcast code without adding the `bigChange:` method to the stock watchers, then run the three examples, you will see some interesting results. In Example One, an exception will be raised saying that `StockWatcher1` doesn't understand the message. In Example Two, it will be a `DependencyTransformer` that doesn't understand the message. In Example Three, no exception will be raised
because the `Stock3` object has no dependencies — it's the instance variable `ValueHolders` that have the dependencies. So, to use broadcasting, you'll have to use the `addDependent:` mechanism. Note that none of the system classes send either `broadcast:` or `broadcast:with:`, and personally, I'd recommend against using them for the above reasons.

## Dependency Considerations

There are two things to be aware of when using the dependency mechanism. First, parents should not send explicit messages to their dependents. Second, and most importantly, it's worth getting into the habit of always breaking dependencies when they are no longer needed.

### Dependency violation

The dependency mechanism is supposed to be a one-way mechanism. The parent or model doesn't know anything about its dependents. It doesn't even know if it has any dependents. However, sometimes people write code so that the parent, in Jim Dutton's phrase, gropes its dependents. Here's an example.

```kotlin
self myDependents do:
    [ :each | (each isKindOf: SomeClass)
        ifTrue: [ each grope ] ]
```

This code violates the basic rule of dependencies — that a parent should have no knowledge of its dependents.

## Breaking dependencies

When the product is almost complete, most organizations try to run it as they think customers will use it. Usually they notice that the product has memory leaks, and that it slowly consumes the available memory. Memory leaks occur because objects are not being garbage collected, and objects are not garbage collected if one or more other objects reference them. When dependencies are not broken, dependent objects are referenced by their parents. If the parent object is held in a class variable or a global, or is referenced by another object in a class variable or a global, or is referenced by an object that is referenced by an object in a class variable or a global, etc., the dependents will never be garbage collected. Sometimes it is extremely difficult to track down exactly why an object is not being garbage collected because the reference path can be very long. In fact it's more difficult to track down memory leaks when the parent is a subclass of Model because the dependencies of non-Models are tracked in one place, in Object's class variable `DependentsFields`.

To reduce the chances of memory leak, you should get into the habit of *always* breaking dependencies when the dependent is no longer needed or the dependent no longer needs the dependency. If the dependency was set up using `addDependent:`, break it with `removeDependent:`. If it was set up with `expressInterestIn:for:sendBack:` or `onChangeSend:to:`, break it with `retractInterestIn:for:`. The breaking of dependencies is usually done in a `release` method such as shown below. In the example, the `MyClass` object removes itself as a dependent of another object, then tells one if its instance variables to break any dependencies it may have, and finally gives its superclass a chance to do any releasing.
MyClass>>release
someObject removeDependent: self.
self someVariable release.
super release.
20

Error Handling

The usual way of handling errors in a procedural language such as C is to return a status from a function call, then check the status in the calling function. If there is a problem, you may take some action in the caller, or more usually, you return from the caller, passing back the status code and possibly logging an error message. Typically, you end up with a lot of code whose sole purpose is to handle errors. It's not uncommon for the majority of the code in a robust application to be associated with error handling.

Smalltalk makes it much easier to focus on the domain problem you are trying to solve by eliminating much of the error handling code. It does this by providing a wonderful mechanism called exception handling. We'll start by taking a look at basic exception handling, then, since there are a lot of additional capabilities, we'll look at these finer points later in the chapter.

The general idea behind exception handling is that you assume everything works, and so you don't check
return values. Of course, sometimes things will go wrong. Perhaps you try to divide by zero, or perhaps you try
to write to a read-only file. These events will raise an exception, which makes its way up the stack, looking for a
signal that can handle it. Rather than checking a status at every level in the call stack (ie, in every method), you
simply need to have an exception handler at the appropriate level in the code where you can take some action.
This is illustrated in Figure 20-1.
<figure><img src="image_21.png" /><figcaption>**Figure 20-1.**
The exception handling mechanism.</figcaption></figure>

To trap, or handle, an exception, you send the `handle:do:` message to an instance of `Signal`. This message takes two blocks as parameters. The parameter to `do:` is the block that you want to execute, usually consisting of several lines of code. The parameter to `handle:` is the block that will be executed if an exception is trapped as a result of a signal being raised while executing the `do:` block. This block takes one parameter, the exception that was raised. The exception contains information about the error which you can use in the handler block. You'll usually see the exception parameter called `:ex`. Let's take a look at how code might look when using an exception handler.

```python
MyRequest>>processYourself
| tape drive |
MySignals appSignal
    handle: [:ex | self myHandleFailure: ex]
    do:
        [self myCheckRequest.
         tape := self myReserveTape.
         drive := self myReserveDrive.
         tape mountYourselfOn: drive.
         self myRespondSuccess].
    self myReleaseTape: tape.
    self myReleaseDrive: drive

MyRequest>>myReserveTape
self tapeName isReserved ifTrue:
    [MySignals appSignal raiseWith: #tapeBusy].
...code to reserve the tape...
```

In `myReserveTape`, we raise an exception if the tape is already reserved. In `processYourself` we have a signal to trap these raised exceptions. You'll see that we don't explicitly test the results of any of the message sends in `processYourself`, relying on the signal to trap the errors. This makes the code much more compact and easy to read. It allows us to focus on the problem we are trying to solve, rather than on the possibilities that things will go wrong.

Let's now look at an example of how you would trap an exception raised by the system classes. The classic example is division by zero. You can find the signals in the `Signal constants` protocol on the class side of `ArithmeticValue`. (In Chapter 29, Meta-Programming we see how to find all the classes with a specified protocol.) If you evaluate the following code, you will get a message displayed on the Transcript.
```
ArithmeticValue divisionByZeroSignal
    handle: [:ex | Transcript cr; show: ex errorString]
    do: [ 4 / 0 ].
```

## Signals and Exceptions

There are two classes that play a role in exception handling: *Signal* and *Exception*. The basic idea is that a signal both raises and traps an exception. When a signal raises an exception in a method, the exception code works its way up (unwinds) the message stack looking for a signal to handle it. Signals that can handle the exception are the signal that raised the exception, and any signal in the raising signal's parent hierarchy (more on this later). If the exception can't find a signal to handle it, it asks *Object noHandlerSignal* to raise an unhandled signal exception. If this new exception can't find a handler, it invokes the *EmergencyHandler*. The default *EmergencyHandler* puts up a Notifier window that displays information about the original exception and gives you the option to bring up a Debugger.

The beauty of this scheme of raised exceptions and exception handlers is that you don't have to have lots of error handling code. Instead, at the level that knows what action to take in response to an error, you create the exception handling code. Then if a lower level method comes across an error, it simply raises an exception.

### Creating your own signal

Exceptions can be raised by the system classes, and your code must be able to handle these. However, for your application, you should raise application defined signals and trap them with application defined signals. When you write your application, you may be several methods deep and realize that you can't continue because of some error. Perhaps you have bad data, perhaps some resource you need is already in use, perhaps some condition has not been satisfied. In any of these cases, you will need to raise an exception that you will trap at a higher level. So you must first create a signal to use.

The easiest way to create a signal is to do `Signal new`, which creates a new signal with *Object errorSignal* as its parent. An alternative way to do the same thing (and, in fact, `Signal new` does this) is `Object errorSignal newSignal`, which we could also do with `self errorSignal newSignal` if our class is subclassed from *Object*. We'll talk more about the details of signal creation later. Now let's create a signal that we can use in our application. We have a couple of choices: we might create several signals, each appropriate for a specific situation, or we might create a more general signal that the whole application can use.

### A single application signal

One approach is to create a single signal for the whole application. This works well in applications where the response to an error is the same, no matter what the error. I've used this approach in applications where we were processing requests from other computers, with no user interaction. If we detected an error, we simply rejected the request, passing back an error number and error message in the response. Here's an example of how we might create and access such as signal.

```
MySignals class>>setValues
    (AppSignal := Object errorSignal newSignal)
    notifierString: 'Application Error:';
    nameClass: self message: #appSignal
```
MySignals class>>appSignal
^AppSignal

## Multiple application signals

Applications that are more user-interface intensive usually have a need for multiple application signals. For example, you might have one or more signals for file errors, one for validation errors, and so on. Then, for example, any time you try to validate something you assume that the validation works unless a validation signal is raised. To create and access these signals we might have something like:

MySignals class>>initialize
    AppSignal := Object errorSignal newSignal notifierString:
        'Application Error:'.
        ValidationSignal := AppSignal newSignal notifierString:
            'Validation Error:'.
            FileSignal := AppSignal newSignal notifierString: 'File Error:'.
            FileNotFoundError := FileSignal newSignal notifierString: 'File Not Found:'.

MySignals class>>fileNotFoundError
    ^FileNotFoundError

MySignals class>>validationSignal
    ^ValidationSignal

Note the signal hierarchy we set up in the `initialize` method. AppSignal is our top level signal, with ValidationSignal and FileSignal as children. FileErrorSignal is a child of FileSignal. Thus we can trap file not found errors with any of FileErrorSignal, FileSignal, AppSignal, or Object errorSignal.

## Overriding errorSignal

Sometimes you may decide to override `errorSignal` to provide different catchall error handling behavior for a class or for a hierarchy of classes. If you override `errorSignal`, you'd like your new behavior to be invoked rather than the default behavior. For example, suppose you have overridden `errorSignal` for `MyClass` and you are sending a message to an instance of `MyClass` that may generate any number of exceptions. You would ask your class rather than `Object` to handle the error. Your handling code will now look like the following.

anInstanceOfMyClass class errorSignal
    handle: [ :ex | ex return ]
    do: [ anInstanceOfMyClass processYourself ].

There are two points to note with this technique. First, you can use it as a standard technique because if a particular class hasn't overridden `errorSignal` it will inherit the default `errorSignal` from `Object`. Second, the behavior you write in your `errorSignal` method must be able to handle signals that are generated by any object since you can't guarantee that the instance of `MyClass` is the only object that will raise an exception.

Another approach is to always use `self errorSignal` as the catchall signal handler rather than `Object errorSignal`. This gives you the opportunity to override the catchall behavior in the class sending the
message rather than using the behavior inherited from Object. If you don't override `errorSignal`, then it is simply inherited.

```
MyClass>>doSomething
self errorSignal
    handle: [ :ex | ex return ]
    do: [ self myDoSomethingElse ].
```

## Central error messages

Let's take a look at what we might do in the `myHandleFailure` method in the example at the beginning of the chapter. We have the exception since it was passed in. Now we need to report or log the error condition. How we do this is very application specific, but let's look at one way of transforming the exception into something a human would understand.

We do this with a central error message facility that contains the error number and error text. The text will directly tell what is wrong, and the number will allow the user to consult an error codes manual for more information about what this error means. In the class side initialization of `MyErrorMessages` we create an `IdentityDictionary` containing instances of `Association`, each association being a message number and the corresponding message text. The dictionary keys are the symbols that are passed as parameters when raising the signal. To retrieve the message number and the message text, we send `numberFor:` and `textFor:` respectively. (You can find code for this example in the file `errormsg.st`.)

```
MyErrorMessages class>>initialize
    "self initialize"
    (Messages := IdentityDictionary new)
        at: #tapeNotFound put: 1 -> 'The specified tape could not be
        found';
        at: #tapeBusy put: 2 -> 'The tape is in use'.

MyErrorMessages class>>numberFor: aSymbol
    ^ (Messages at: aSymbol ifAbsent: [0 -> nil]) key.

MyErrorMessages class>>textFor: aSymbol
    ^ (Messages
        at: aSymbol
        ifAbsent: [nil -> 'Code ', aSymbol printString, ' not found'])
        value.
```

Now we just need to see how we would use this message facility when handling the failure. In `myHandleFailure`: we extract the error number and the error text from the centralized error message facility. Next, we append any additional text that was given when the signal was raised. Then we take some domain specific action to report the error.

```
MyRequestClass>> myHandleFailure: anException
    number := MyErrorMessages numberFor: anException parameter.
    text := MyErrorMessages textFor: anException parameter.
    anException localErrorString notNil ifTrue:
        [text := text, ' - ', anException localErrorString].
    .... now do something domain specific with the number and text
```
In this example, we generate the message text when we trap the exception. This is acceptable in situations where we don't need to add information about the values of the objects at the time of the error. In other situations we may need to also log or display the values of objects. To pass back information, we could create an ExceptionParameter class that contained the error symbol, a collection of parameters, and possibly an additional error string. We would then raise the exception with raiseWith:, passing our ExceptionParameter as the parameter, and have the exception handling code construct an error message from the ExceptionParameter. (An alternative approach is to use the mechanisms described below in the section on Parameter Substitution, and have the exception create a fully formed string.)

The scheme described above is fairly simple since we only have error numbers and error text. In a production system we would probably have a MyMessages superclass that defined most of the behavior, then MyErrorMessages and MyInformationMessages as subclasses. We would also store more information with each message, such as the message severity and message categorization to help route error responses and error reporting. One approach would be to code this information into the message string, but this would not be very object-oriented. A more powerful and more object-oriented approach would be to create MyMessage objects to put in the dictionary, rather than instances of Association. We might have something like the following. It would be straightforward to write methods to extract the message text and categorize and sort it for easier viewing.

MyErrorMessages class>>initialize
"self initialize"
(Messages := IdentityDictionary new)
at: #tapeNotFound
put: (MyMessage
number: 1
severity: #warning
routing: 'TN'
text: 'The specified tape could not be found');
at: #tapeBusy
put: (MyMessage
number: 2
severity: #warning
routing: 'TN'
text: 'The tape is in use').

The severity codes might include #information, #warning, #error, #fatal, while the routing information tells what type of message this is. In this example, T refers to tapes and N refers to the non-existence of things. We might further encapsulate information and create a specific routing object rather than code routing information into a string. We might also create subclasses of MyMessage for errors and warnings (for example, MyErrorMessage and MyWarningMessage). By having subclasses that encapsulate the information, we could later decide to encapsulate behavior specific to the message type.

The severity and routing information allows clients of the messaging system, such as other computers, the error log, and the system console, to register for the types of messages they want to receive. If an error message is created in response to a request, the message would be sent to the originator of the request. It would also be sent to a central message router that would distribute it to all message clients whose registration criteria matched the information in the message.

If you are using ENVY, you might consider using the provided error reporting mechanism, which uses the ErrorReporter class. There is more about ENVY in Chapter 34, ENVY.
## More on Signal Creation

We've seen the basics of creating a signal, so now let's take a look at some of the details. Signals can be proceedable or non-proceedable, you can specify the string to be displayed in a Notifier window, and you can specify the message that will return the signal. Additionally, we'll take a look at parents of signals, and how signal trapping works within the parent hierarchy.

### Specifying the proceedability of the signal

Signals can be proceedable or non-proceedable. A proceedable signal allows the exception handler to proceed from the point where the exception was raised. In general you won't do this and so won't care about this feature, but it's useful to know. When you send `newSignal`, you inherit the proceedability of the parent signal. `Object errorSignal` is proceedable, so `Object errorSignal newSignal` gives you a new proceedable signal with `Object errorSignal` as its parent. If you care about the proceedability, you can use the `newSignalMayProceed` message with a Boolean parameter that specifies whether the signal is to be proceedable. For example, `Object errorSignal newSignalMayProceed: true` gives you a proceedable signal. If you want to be able to proceed from an exception, you must raise exceptions by sending your signal a message from the `raiseRequest` family rather than the `raise` family.

### Notifier strings and inspector information

There are two other aspects to consider when creating a new signal. If you send `notifierString: aString` to an instance of `Signal`, you set the default string that is returned by the `errorString` message — the string that will be displayed at the top of any Notifier window raised by this signal. If you send `nameClass: aClass message: aSymbol` to the signal, you are by convention specifying that you can get this signal by sending the message specified by `aSymbol` to the class specified by `aClass` (this is really just a documentation aid; you'll still have to write the method that returns the signal). Additionally, `aClass` and `aSymbol` are stored in instance variables in the signal and give inspectors more information to display. For example, you might create a signal by doing the following, also remembering to write the `appErrorSignal` method.

```
(AppErrorSignal := self errorSignal newSignal)
    notifierString: 'Application Error: ';
    nameClass: self message: #appErrorSignal
```

## Parents handling signals

Earlier we trapped a division by zero error using `ArithmeticValue divisionByZeroSignal`. Now let's trap the same error with the parent signal, `ArithmeticValue domainErrorSignal`. Then we'll trap the signal with its parent, `ArithmeticValue errorSignal`, then with its parent, `Object errorSignal`. You can see how the signals are created from their parents in the class initialization of `ArithmeticValue`.

```
ArithmeticValue domainErrorSignal
    handle: [:ex | Transcript cr; show: ex errorString]
    do: [ 4 / 0 ].
```
```
ArithmeticValue errorSignal
    handle: [:ex | Transcript cr; show: ex errorString]
    do: [ 4 / 0 ].
```

```
Object errorSignal
    handle: [:ex | Transcript cr; show: ex errorString]
    do: [ 4 / 0 ].
```

Since we also know how to create new signals of our own, let's see another example of how the parent of a signal can trap exceptions raised by the signal, but other signals derived from the same parent (ie, siblings of the signal) can't trap the exception. In our example, `parent1` and `parent2` are two signals with the same parent, `Object errorSignal`. `child2` has `parent2` as its parent. If we ask `parent1` to trap an exception raised by `child2`, it doesn't. If we ask `parent2` to trap the exception, it does. Try the code below twice, once with `parent1` handling the exception and once with `parent2` handling it. Moral of the story: an exception can be trapped by the signal that raised it, or by its parent or grandparent, ..., up to `Object errorSignal`.

```perl
parent1 := Object errorSignal newSignal notifierString: 'Error1:'.
parent2 := Object errorSignal newSignal notifierString: 'Error2:'.
child2 := parent2 newSignal.
parent1
    handle: [:ex | Transcript cr; show: 'in handler']
    do: [child2 raise].
```

Signal collections

If your application can raise several different signals but the way of dealing with the exception is the same for all the signals, you have two alternatives. You could use a generic signal, such as `Object errorSignal`, or a common parent signal to handle all the possible exceptions. Or, if you know exactly which signals can be raised, you can use a `SignalCollection`. To do this, add the signals you want to trap to the `SignalCollection`, then send `handle:do:` to the `SignalCollection`. When a signal is raised, it looks at each signal in the collection until it recognizes one. You can build the `SignalCollection` in one place then reuse it in different places.

Try the following example twice, reversing the order of the statements in the `do:` block. You'll get a different exception reported on the Transcript.

```perl
sigCollection := SignalCollection
    with: Dictionary key foundingSignal
    with: Dictionary value not found Signal.
sigCollection
    handle: [ :ex | Transcript cr; show: ex errorString]
    do:
        [Dictionary new at: 3.
         Dictionary new key At Value: 4].
```

How useful are `SignalCollections`? I've worked on applications where they were not very useful because it was easier to have the top level application signal or `Object errorSignal` do the trapping. I've also worked on applications where we used `SignalCollections` because we needed to be specific about the errors we were trapping. The VisualWorks system classes use a `SignalCollection` only two times, and one of those is an empty collection!
## Handler lists / collections

If you have a set of signals you want to trap but you want to take different actions for each exception, you can use a set of nested handlers. For example,

```
signalOne
    handle: [:ex | some code]
do: [signalTwo
    handle: [:ex | some code]
do: [signalThree
    handle: [:ex | some code]
do: [some application code]]
```

If there are a lot of signals you want to look for, the code will get pretty messy. The *HandlerCollection* (VisualWorks 2.0) or *HandlerList* (VisualWorks 2.5) class provides a shorthand way of doing the same thing. The handlers will still be nested when the code is executed, but the code is a lot tidier and is therefore easier to understand and maintain. Here's the above example coded using a *HandlerList* — note that since the handlers are really nested, the last signal added is the first signal that will get a chance to trap the exception. So put the most general signals first and the most specific last. Again, you can build the *HandlerList* in one place and reuse it in different places.

```
(handlerList := HandlerList new)
on: signalOne handle: [:ex | some code];
on: signalTwo handle: [:ex | some code];
on: signalThree handle: [:ex | some code].
handlerList handleDo: [some application code].
```

How useful are *HandlerLists*? Again, I've worked on applications where we never used them. I've also worked on applications where we wanted to trap errors generated by the file system, and give the user a different message for each type of `error`. In my experience, *HandlerLists* are most useful when handling errors generated by the interaction of the Smalltalk image with the operating system, where the action you take depends on the exact problem detected. The VisualWorks system classes use a *HandlerList* or *HandlerCollection* only once.

(In VisualWorks 2.5, *HandlerCollection* was replaced with *HandlerList*. Unless you have been subclassing from *HandlerCollection*, the behavior is identical.)

## Passing information with an Exception

Let's now look at the various ways of passing information with the exception. We'll examine only non-proceedable signals; for proceedable signals you substitute `raiseRequest` for `raise` in all the examples.

To get a string describing the exception, you send the `errorString` message to the exception. The signal's notifier string and the parameters to the raise message are all used when creating the error string, and in the following examples, we will show how they affect the error string. Notifier windows display the value returned by `errorString`.

### raise

The `raise` message simply raises an exception, passing back no information.
**raiseWith: aParameter**

The `raiseWith: aParameter` message passes back information in the parameter. To retrieve the parameter, send `parameter` to the exception. In our example above, we passed the symbol `#tapeBusy` as the parameter, and then used it to look up the error message.

**raiseErrorString: aString**

The `raiseErrorString: aString` message passes back a string. You can access the string by sending `localErrorString` to the exception. The value returned by `errorString` depends on spaces in aString.

The rule is:

* aString has no space in front - replace notifier string

* aString has a space in front - append aString to notifier string

**raiseWith: aParameter errorString: aString**

The `raiseWith: aParameter errorString: aString` message passes back both a parameter and a string. You can access the parameter by sending `parameter` to the exception and the string by sending `localErrorString` to the exception. The value returned by `errorString` depends on spaces in aString.

The rule is:

* aString has no space in front - replace notifier string

* aString has a space in front - append aString to notifier string

* aString has a space at the end - append parameter to aString

**Parameter Substitution**

At the time you raise an exception you have access to all the information that is relevant to the error. VisualWorks provides a parameter substitution mechanism where you can raise an exception, passing a template string and a collection of parameters to be substituted. (If you are using a centralized messaging facility, you could get the message template from it, using a symbol as the lookup key.) The exception substitutes the parameters, generating a fully formed message. However, my preference would be to create the ExceptionParameter object that we discussed above since this provides more power and flexibility.

The parameter substitution mechanism is different in VisualWorks 2.0 and 2.5, so we'll look at both. In both messages below, the template is a string with embedded formatting information. The parameter is expected to be a collection, where each element of the collection corresponds to a formal parameter in the template string. Sending `parameter` to the exception will return the parameter collection, and sending `localErrorString` will return the expanded string. The `errorString` message conforms to the space rules shown in `raise:ErrorString: above`.

**raiseWith: errorTemplate:**

The `raiseWith: aParameterCollection errorTemplate: aString` message is the parameter substitution message used in VisualWorks 2.0. The template string contains embedded percent signs
(%). The string will be expanded before the handler gets to trap the exception, with the % being replaced by the `printString` representation of the appropriate collection element. For example, the following brings up a Notifier window with the message: *Unhandled exception: Received bad value 3 and bad value 'm:\temp'*.

```
Object errorSignal
    raiseWith: #(3 'm:\temp')
    errorPattern: 'Received bad value % and bad value %.'
```

### `raiseWith:errorPattern`:

The `raiseWith`: `aParameterCollection` `errorPattern`: `aString` message is the parameter substitution message used in VisualWorks 2.5. It provides a new, more powerful parameter substitution mechanism using a new family of messages (`expandMacros`). For more information on the parameter substitution options, see Chapter 12, Strings. For example, the following brings up a Notifier window with the message: *Unhandled exception: Received bad value 3 and bad value m:\temp*.

```
Object errorSignal
    raiseWith: #(3 'm:\temp')
    errorPattern: 'Received bad value <1p> and bad value <2s>.'
```

## Handling the exception

There are several ways to handle the exception in the `handle:` block of the `handle:do:` message. Remember that the block will look something like `[:exception | some code]`, where the exception is passed in as the parameter. If you hit the right bracket of the handle block, the return value of the block (ie, the value of the last statement executed) will be the value returned from `handle:do:`. If there is no code in the block, the exception will be returned.

Alternatively, you can send a message to the exception as the last thing in the block — this is the preferred approach because it gives the exception a chance to gracefully unwind the stack. The messages you can send are `return`, `returnWith:`, `reject`, `restart`, `restartDo:`, `proceed`, `proceedWith:`, and `proceedDoing:`. We will look at some of these messages. For the others, you'll have to examine the system code and read the manuals.

### `return`

The `return` message returns `nil` from the handle block. It's the same as doing `returnWith: nil`. Note that `return` leaves you in the method containing the exception handler. If you don't want to do anything in the handler block, it's good practice to do `ex return`. The following code prints `nil` to the Transcript.

```
Transcript cr; show:
(self errorSignal
    handle: [:ex | ex return]
    do: [self errorSignal raise]) printString.
```
## returnWith:

The `returnWith:` message allows you to set a value as the return value from `handle:do:`. The parameter to `returnWith:` will be the return value. Note that `returnWith:` leaves you in the method. The following code prints 3 to the Transcript.

```perl
Transcript cr; show:
(self errorSignal
    handle: [:ex | ex returnWith: 3]
    do: [self errorSignal raise]) printString.
```

## reject

The `reject` message allows you to take some action then reject the exception, or reject the exception based on some criteria. In the following example, in the handle block we print to the Transcript then reject the exception. Since the exception is rejected, it continues to look for a handler, but doesn't find another one, so it raises a Notifier window.

```perl
self errorSignal
handle: [:ex |
    Transcript cr; show: ex errorString.
    ex reject]
do: [self errorSignal raiseWith: 3 errorString: 'Error '].
```

## restart

The `restart` message allows you to figure out what caused the exception to be raised, fix the condition, then restart the `handle:do:` expression. The following code gives you a chance to correct the error that you get if you divide by zero.

```perl
self errorSignal
handle: [:ex |
    Dialog warn: 'You divided by zero'.
    ex restart]
do: [| answer |
    answer := Dialog request: 'Divide 4 by what?' initialAnswer:
    '0'.
    Transcript cr; show: (4 / answer asNumber) printString].
```

## restartDo:

The `restartDo:` message allows you to figure out what caused the exception to be raised, possibly fix the condition, then restart execution with a different code block. While you can use `^` in a `handle:` block to return from the method, `restartDo:` is the recommended way of doing this. For example, `ex restartDo: [^nil]` exits the method, returning `nil`.

```perl
MyClass>>myMethod
someSignal
    handle: [:ex | ex restartDo: [^nil]]
    do: [some code that raises an exception]
```
**self error:**

Another way to raise an exception is to send the `error:` message, passing a string as a parameter. By default this raises a Notifier window and allows you to bring up a Debugger. To change the default behavior, you can override `error:`. If you are using the application signal mechanism described above and you have a single centralized message file in your image, you could write, for example, `Object>>error:args:string:` to take a symbol, an array of arguments, and an additional string as arguments. It would handle raising the exception in the appropriate way. To invoke it you would do something like

```
self error: #tapeNotFound args: (Array with: tapeName with: driveName) string: nil.
```

A more elegant approach would be to have your own subclass of Object, say `MyObject`, and to defined `error:args:string:` on MyObject. All application objects that used to be subclassed from Object would now be subclassed from MyObject.

**doesNotUnderstand:**

If your code sends a message that is not understood, eventually the `doesNotUnderstand:` message will be sent. The default `doesNotUnderstand:`, implemented by Object, raises a Notifier window. You can override `doesNotUnderstand:` if you want to do anything specific such as logging an error.

**valueNowOrOnUnwindDo:**

Suppose you have code that should be executed both after normal completion of a sequence of statements, and if an exception is raised. You can wrap the regular code in a block and send it the message `valueNowOrOnUnwindDo:`, passing as the parameter a block containing the code you always want executed. A good example of this is closing a file. You'd like to close the file after successfully reading it, and also if an exception is raised while reading the file. Here's an example of how to use this technique.

```
stream := self myFilename readStream.
[ self readFile: stream ]
valueNowOrOnUnwindDo:
    [ stream close ].
```

**Emergency Exception Handler**

If an exception can't be handled, the `EmergencyHandler` will be invoked. The default `EmergencyHandler` is defined during class initialization for `Exception`, and it raises a Notifier window. You can change the `EmergencyHandler` by sending `Exception` the class message `emergencyHandler:`, where the parameter is a block that takes two arguments: the exception and the context. For example, try the following (after saving any changes you want to keep).

```
Exception emergencyHandler:
    [:ex :context |
        Dialog warn: 'Quitting: ', ex errorString.
        ObjectMemory quit].
3 next.
```
Once the emergency handler has done its thing, it attempts to re-execute the code that caused the exception. So, unless the emergency handler quits the Smalltalk image or starts a new thread of execution, you will end up in an infinite loop.

## noHandlerSignal

As we saw earlier, if an exception can't find a signal to handle it, it asks `Object noHandlerSignal` to raise an unhandled signal exception. If this new exception can't find a handler, it invokes the `EmergencyHandler`. However, the new `noHandlerSignal` exception is raised in the original context so we still have an opportunity to trap it. To see an example of how this works, create a class with the following methods.

```java
MyClass>>methodOne
    self methodTwo

MyClass>>methodTwo
    Signal noHandlerSignal
    handle: [:ex | Transcript cr; show: 'methodTwo - ', ex
    parameter errorString]
    do: [self methodThree]

MyClass>>methodThree
    self foo
```

If you now execute `MyClass new methodOne`, you will see the following on the Transcript:

```
methodTwo - Message not understood: #foo
```

The way this works is that `methodThree` sends the message `foo`, which is not implemented and thus raises a `messageNotUnderstood` exception. The exception cannot find a handler for itself anywhere in the stack, so it raises a `noHandlerSignal` exception, with the original exception stored in the `parameter` instance variable of the new exception. In `methodTwo` we have a handler for the new exception, so we trap it and print out some information. Note that since the `noHandlerSignal` exception contains the original exception in its `parameter` variable, we have to print `ex parameter errorString` to get information about the original error.

Since the `noHandlerSignal` exception is raised only if no handler is found for the original exception, we should be able to add an exception handler in `methodOne`, and have this invoked instead of the handler in `methodTwo`. Modify `methodOne` to look like the following:

```java
MyClass>>methodOne
    Object messageNotUnderstoodSignal
    handle: [:ex | Transcript cr; show: 'methodOne - ', ex
    errorString]
    do: [self methodTwo]
```

If you now execute `MyClass new methodOne`, you will see the following on the Transcript:

```
methodOne - Message not understood: #foo
```

This technique gives us a way to create a “last resort” exception handler. By wrapping our code in a `Signal noHandlerSignal` exception handler, we in effect say “I'll give someone else an opportunity to handle any exception that is raised, but if no one else wants to handle it, I'll take care of it myself.”
## Exceptions and Processes

Unfortunately, Smalltalk doesn't do a good job of handling exceptions raised in forked processes. The problem is that when a process is forked, it gets its own stack context. When an exception is raised in a forked process, it bubbles up the stack until it is either handled or it raises a Notifier window. Because the forked process has a different context than the process that forked it, the exception never gets into the stack of the forker.

This means that each forked process must have its own exception handling code if you want to trap exceptions. What you do next, after trapping the exception, depends on the application and how it is structured. If you have an application where there is a central dispatcher that gets requests and runs each request in its own forked process, each request could have an instance of SharedQueue which it uses to communicate back to the forker. For an example of this, see the section named *Running tests that time out* in Chapter 30, Testing.

For a more complete discussion of handling exceptions in a multi-process environment, see the two part article, *Cross-Process Exception Handling*, by Ken Auer and Barry Oglesby in *The Smalltalk Report*, January 1994 and February 1994 (the first part is mis-titled, being called *Cross-Purpose Exception Handling*).

## When to look for errors

There are different philosophies on when to look for error conditions. The idea has made it into software engineering folklore that you should trap errors as soon as possible. This makes sense when we are dealing with user interfaces because it's reasonable to let users know about errors as soon as possible (of course, it's even better to write applications that prevent users making errors).

On the other hand, leaving aside user interface code, there's no reason to trap an error before it absolutely needs to be detected. There's no reason to have a whole hierarchy of methods all checking the validity of the same parameters. Most of them won't even care what the value is and will simply pass it on. It makes a cleaner application to check the validity of things only when it's vital that they are valid. Then, and only then, raise an exception.
21

Debugging

This chapter is not so much about debugging, as about debugging with Smalltalk. It won't necessarily help
you become a better debugger, but it will help you learn what tools are available to help debug a Smalltalk
application. One hint to becoming a better debugger is to explain the problem to someone else. The act of
thinking the problem through clearly enough to put into words often leads you to a solution without the other
person having to say anything. If you can distill out the critical factors that make this so, you can become a better
debugger even when no one else is present.

Bringing up a Notifier window

<figure><img src="image_22.png" /><figcaption>**Figure 21-1.**
A notifier window.</figcaption></figure>

The basic mechanism for halting execution and giving you a Notifier window, as shown in Figure 21-1, is to
send the halt message in your code. The normal way of doing this is to send it to self. For example,

self halt.
When the `halt` message is sent, the `halt` method raises a signal (*Object haltSignal*), which eventually invokes the *EmergencyHandler*. The default emergency handler places a Notifier window on the screen which gives you the option to debug the program. (Actually, it asks the class *ANTS NotifierView* to open. NotifierView opens a Debugger which gives you the option of debugging, proceeding, terminating, etc. Since the window you get when you press Debug is what is usually thought of as the Debugger, it seems convenient to refer to the initial window as a Notifier window.) If you have a string you'd like displayed in the Notifier window, send the `halt:` message instead of `halt`. For example,

```python
self halt: 'My string to display'.
```

While sending one of the `halt` messages is the normal way to bring up a Debugger, you can also send `notify:` with a string parameter or `error:` with a string parameter. For example,

```python
self notify: 'Count is now over 100'.
self error: 'Should not get here'.
```

## Using a Debugger window

<figure><img src="image_23.png" /><figcaption>**Figure 21-2.** A debugger window.</figcaption></figure>

From the Notifier window, you can press the Debug button to bring up a Debugger. In the top window, the Debugger shows you several lines of the stack trace. By selecting one of the lines, you can see the source code for that method. You can examine all the parameters and temporary variables for the method, and all the class and instance variables for the message receiver. If the stack trace does not show enough methods, you can show more of the stack by selecting the *more stack* mouse menu option in the upper pane.

The main window shows the code. In this window you can highlight code segments and execute them, you can modify the code and accept it, or you execute the code one message at a time. To simply execute the next
message send, press the step button. If you want to trace through the message send and go into the method that is executed, press the send button. The Debugger will stop at the first message in the new method.

If you modify the code and accept it, execution will start again at the beginning of the method if you press restart or proceed. This allows you to replay the application to try and recreate a problem (assuming that the application can be restarted). Go down the stack to a method that you can get useful debugging information from if you restart. Adding then removing a space forces recognition that a change has happened to the code and you can then accept the method. Now you can use the step and send keys to step through the code and try to understand why the problem occurred.

A useful technique for writing new code is to write most of the code in the Debugger. Write your main method as a series of message sends that invoke supporting methods to do the real work. Each supporting method will initially consist of nothing more than `self halt`. When you run your application, you will get a Debugger on the first supporting method. You can now write the real code in the Debugger, using it to help you understand the context and the appropriate message sends, and to test out possible options.

Another use for the Debugger is to step through your code, one line at a time, when you first run your application. In doing this, you will inevitably gain insights into the code. You'll see obvious mistakes that you made, and obvious ways to restructure your code. Stepping through your code in this way will almost always help you improve the code, making it less likely that you will need the Debugger to later track down bugs.

## Inspectors

At the bottom of the Debugger are two Inspectors. The left one shows class and instance variables, while the right one shows parameters and temporary variables. When you click on a variable name, its value will be displayed in the right hand window of the Inspector. To open a new Inspector, you can either highlight a variable name or a code sample in the code window then choose *inspect* from the right mouse button menu, or you can select a variable name in an Inspector and choose *inspect* from the mouse menu.

(When you open an Inspector, the object you want to inspect is sent the `inspect` message. Most objects inherit `inspect` from `Object`, which opens a generic Inspector. However, some objects, such as `OrderedCollection`, `Dictionary`, and `String` override `inspect` to open a specialized Inspector. You can use `basicInspect` to open a generic Inspector.)

## Modifying values in an Inspector

In the examples that follow, we will use a class called `ModifyingValues`, with three instance variables. The code for this example can be found in the file `debug.st`. To bring up the Debugger window, evaluate `ModifyingValues new initialize`. The initialize method is as follows.

```perl
ModifyingValues>>initialize
    color := #blue.
    size := 5 -> 10.
    things := OrderedCollection with: 'one' with: 'two' with: 'three'
        with: 'four'.
    self halt: 'Use an inspector to modify the values'
```

If you want to replace a value in a variable, use the Inspector windows at the bottom of the Debugger. Highlight the variable, which causes the contents to be displayed on the right hand window of the Inspector.
Replace the value in the window with the new value, and choose *accept* from the mouse menu. In the following example, replace the value `#blue` with another value, then accept the change.

<figure><img src="image_24.png" /><figcaption>**Figure 21-3.** Changing a value in the Inspector.</figcaption></figure>

On the other hand, if you want to replace the *contents* of an object that is being referred to by a variable, you will need to bring up a new *Inspector* on the variable. You can do this to modify an instance variable of an object, or to modify the contents of a collection. In this example, we want to modify the *things* collection, removing one item and adding another. If we bring up an *Inspector* on the collection, we get a window like the following. Now we select an item in the collection and use the mouse menu to delete it, or we can use the mouse menu to insert a new item.

<figure><img src="image_25.png" /><figcaption>**Figure 21-4.** Inspecting an OrderedCollection.</figcaption></figure>

In our example, the *size* variable is an Association. If we want to replace part of the contents of *size*, we again bring up a new *Inspector* on the variable. We then select the variable we want replaced, change the value, and accept the new value.
<figure><img src="image_26.png" /><figcaption>**Figure 21-5.** Inspecting an Association.</figcaption></figure>

## Halting

If you have several occurrences of `self halt` in the code, it can be difficult to figure out where a particular Notifier window came from, especially if you are using forked processes. Sometimes you want to proceed a sequence of halts until you find a halt generated from a particular place. The Notifier windows do show some of the stack, but I find it easier to look at the text at the top rather than scan the stack. There are two ways of doing this: you can modify system methods or write your own.

### Modifying halt and halt:

The easiest way to provide context information is to modify `halt` and `halt:` for `Object`. Some people recommend against modifying `Object`, but this is a change that is easy to reproduce when you get a new version of Smalltalk, and it doesn't much matter if you don't make the change. Modifying the development tools and development environment tends to be less controversial than modifying system classes that will be used in the deployed application. In both these examples we want to find the sender of the message, and we get this from `thisContext sender`.

In `halt`, modify the `errorString:` parameter to be `'Halt in ', thisContext sender printString`.

In `halt:`, modify the `errorString:` parameter to be `'Halt in ', thisContext sender printString, ' - ', aString`.

### Writing your own myHalt and myHalt:

If you prefer not to modify system methods, or you have organization rules that prohibit this, then you could instead write new methods on `Object`, `myHalt` and `myHalt:`, which you would use instead of `halt` and `halt:`.

```python
Object>>myHalt
Object haltSignal
raiseRequestWith: thisContext
errorString: 'Halt in ', thisContext sender printString
```
Object>>myHalt: aString
Object haltSignal
raiseRequestWith: thisContext
errorString: 'Halt in ' , thisContext sender printString , ' -
' , aString

Conditional halting

There are times when you don't want to halt every time through. One option is to conditionally do the self halt. Alternatively, you could write a haltIf: method on Object. Here are examples of the two approaches.

(some condition) ifTrue: [self halt]

Object>>haltIf: aBlock
aBlock value ifTrue:
    [Object haltSignal
        raiseRequestWith: thisContext
        errorString: 'Halt in ' , thisContext sender printString]

self haltIf: [some condition]

Sometimes you don't have a specific condition you want to test for. You can see things happening on the
screen or on the Transcript, and after a while you want to trigger the self halt. You need some stimulus to
tell the debug code that you are ready, and one obvious way is to hold down a key or key combination that is not
pressed in normal operations. For example, we might write an altCtrlHalt method that only halts when the
Alt and Ctrl keys are held down at the same time (you could of course write a similar altHalt, ctrlHalt,
shiftHalt, etc.)

Object>>altCtrlHalt
"Note the two mechanisms we can use for detecting if the key is
down.
The first one is about 50% faster than the second."
(InputState default altDown
and: [ScheduledControllers activeController sensor ctrlDown])
ifTrue: [Object haltSignal
raiseRequestWith: thisContext
errorString: 'Halt in ' , thisContext sender printString]

You could probably leave altCtrlHalt message sends in the code for long periods of time, and possibly
leave them in customer code for over-the-phone debugging (assuming the stripped-down image contains the
classes necessary to run the Debugger). If you don't want to halt, but would rather log something or display
something to the Transcript, you can use altCtrlDo:.

Object>>altCtrlDo: aBlock
(InputState default altDown and: [InputState default ctrlDown])
ifTrue: [aBlock value]

Halting without adding a halt

A useful technique for stepping through code without having to add self halt to a method is to do the
following. If you highlight the code and execute it, you will get a Debugger window and will be able to step into
someMethod.
```kotlin
self halt.
someObject someMethod.
```

## Writing information to a file or the Transcript

Sometimes you may want to write information about the context to a file or to a Transcript for debugging. Here's an example of a class that does some simple logging. The code that follows prints a string followed by a printout of the stack, showing all the message sends that you made. It will log to either the Transcript or to a file, depending on whether the *file* variable has been set (the setting method is not shown here). This code can be found in the file `debug.st` (to run it, evaluate `LoggerExample new run` in the Transcript after filing it in).

```kotlin
Logger>>contextString
| context stream |
stream := (String new: 100) writeStream.
context := thisContext sender.
["Unwind the stack until we are out of Logger"
 self == context receiver] whileTrue: [context := context sender].
"Unwind the stack as far as possible, printing out as we go"
[context notNil and: [context receiver notNil]]
whileTrue:
    [stream cr; print: context.
     context := context sender].
^stream contents

Logger>>log: aString
| contextString |
contextString := self myContextString.
Object errorSignal
    handle: [:ex |file := nil.
        ex restartDo: [self log: aString]]
    do: [self myWrite: self myWriteStream string: aString context:
         contextString]

Logger>>myWrite: aStream string: aString context: aContextString
[aStream cr; cr; nextPutAll: aString; nextPutAll: aContextString;
flush]
valueNowOrOnUnwindDo:
    [aStream == Transcript ifFalse: [aStream close]]

Logger>>myWriteStream
^file notNil
    ifTrue: [file appendStream]
    ifFalse: [Transcript]
```

You can use the class ` NotifierView` to give you stack information by doing the following message send, which returns a string containing a stack dump. The second parameter specifies the depth, or number of stack references to return. If the stack is not as deep as the depth you specify, the string contains the full stack. Note that the message is in the *private* protocol, which means it might be changed or removed.

` NotifierView shortStackFor: context ofSize: 99`

For more information on logging debug information, see the article *A Trace Logger*, by Alec Sharp and Dave Farmer, in The Smalltalk Report, Nov/Dec 1994.
## Audible and Visible information

Sometimes you may simply want to know when something is happening. If you are on a system that can make a bell sound, you can put the following code into methods to indicate that they are being executed:

```
Screen default ringBell.
```

If you don't want to ring a bell, you can flash a widget. Choose a widget (for example, a widget with the name `saveAB`), then send it the `flash` message. For example

```
(self builder componentAt: #saveAB) flash.
```

## Monitoring activity of objects

If you have an object that doesn't seem to be behaving itself but you can't figure out why, you can create an object to watch it and report on its behavior. To do this, create a `Watcher` class as follows. Notice that the superclass is `nil`. You'll get a warning message about a `nil` superclass when you accept the class definition for `Watcher`, and also if you fileIn the code. When you get the warning window, press the Proceed button.

```nil
nil subclass: #Watcher
instanceVariableNames: 'watchedObject '
classVariableNames: ''
poolDictionaries: ''
category: 'Debugging'

Watcher class>>on: anObject
    ^self new initializeWatcher: anObject

Watcher>>initializeWatcher: anObject
    watchedObject := anObject

Watcher>>doesNotUnderstand: aMessage
    | result |
Transcript
    cr; print: thisContext sender; nextPutAll: ' sent ';
    print: watchedObject class; nextPutAll: '>>'; nextPutAll:
    aMessage selector asString.
    aMessage arguments size > 0 ifTrue:
        [Transcript print: aMessage arguments].
result := watchedObject
    perform: aMessage selector
    withArguments: aMessage arguments.
Transcript nextPutAll: ' ^'; print: result; flush.
    ^result
```

When you've defined the class and its methods, file out the code, remove the class, then file the code back in. This will create any additional needed methods. (In particular, it creates the method `class`. Since `Watcher` is subclassed off `nil`, it has some special needs.) To use the `Watcher`, instead of creating your object in the code, create a `Watcher` on the object by doing something like

```
myObject := Watcher on: (MyClass new).
```

In your code, all the messages that are being sent to `myObject` will actually go to the `Watcher`, which keeps the "real" object in an instance variable. Being subclassed off `nil`, the `Watcher` doesn't understand many
messages, so messages sent to it will end up invoking the `doesNotUnderstand:` method. In that method we log the message and its arguments, and who sent the message. We then pass the message on to its correct destination, log the return value, then return the return value. It would be easy enough to modify this code if you wanted to log to a file rather than to the Transcript. Here's an example, written on the class side of Watcher, followed by the results.

```
Watcher class>>example
"self example"
| array |
array := self on: (Array new: 3).
array at: 2 put: 'hello'.
array at: 2.
array printString.
array size

Watcher class>>example sent Array>>at:put:#{(2 'hello')} ^'hello'
Watcher class>>example sent Array>>at:#{(2) ^'hello'
Watcher class>>example sent Array>>printString ^'#{(nil ''hello''
nil)'}'
Watcher class>>example sent Array>>size ^3
```

## A brief aside

As an aside, the technique of overriding `doesNotUnderstand:` makes it possible to add instance specific behavior to instances of a class. Suppose MyClass has an instance variable called *methods* (with accessors) which contains an IdentityDictionary. The Dictionary could contain associations of methods and blocks of code. MyClass would override `doesNotUnderstand:` as follows.

```
MyClass>> doesNotUnderstand: aMessage
| codeBlock |
codeBlock := self methods at: aMessage selector ifAbsent: [^nil].
codeBlock valueWithArguments: aMessage arguments
```

Here's an example of how it might be used. When you execute this code, 'YES' is printed to the Transcript.

```
instance := MyClass new.
dictionary := IdentityDictionary new.
dictionary at: #yes put: [Transcript cr; show: 'YES'].
instance methods: dictionary.
instance yes.
```

This concept can be extended further to give *roles* to objects. To use an everyday example, most people have several roles during the day. For example, a woman may at different times play the role of wife, mother, employee, boss, shopper, and chauffeur. Each role has different behaviors. Smalltalk does not have multiple inheritance, but we can emulate the concept with roles. Suppose we have a RolePlayer with an instance variable of *role*. Instead of keeping a Dictionary of methods and blocks of code, we would create a Role object and pass the Role object to the RolePlayer. Then, if a message is not understood by the RolePlayer, it would pass it on to the Role. For example,

```
RolePlayer>>doesNotUnderstand: aMessage
role notNil ifTrue:
    [^role perform: aMessage selector withArguments: aMessage
        arguments]
```
```
ChauffeurRole>>pickUpKids
Transcript cr; show: 'I am picking up the children'
```

Then, if we execute the following code, we see the message 'I am picking up the kids' printed to the Transcript.

```
person := RolePlayer new.
person role: ChauffeurRole new.
person pickUpKids.
```

You can find the code for this example in the file `role.st`. The topic of roles is quite a bit more involved than described here and is beyond the scope of this book. However, what we've just described may give you ideas for solutions to your own application problems.

## Objects not being garbage collected

During development, the issue of objects not being garbage collected doesn't usually arise because your focus is getting the functionality written. However, as you approach shipping time, you often find that the memory used by your image keeps growing as the application is used. This usually means that there is a memory leak because you have objects that are not being garbage collected. When an object is not garbage collected, it means that it is still being referenced by at least one other object. And this probably means that the other object is not being garbage collected either.

If you think you have objects hanging around longer than they should, start by doing a garbage collection. You can do this from the File menu in the Launcher, or by doing one of the garbage collection operations in the `collecting garbage` class side protocol of `ObjectMemory`. Try one of the verbose operations, which give you information on the garbage collection done. Once you've cleaned up the garbage, you can look at all instances of the class you think has unreclaimed instances by inspecting

`SomeClassName allInstances.`

If there are several instances, by inspecting the instance variables, you may be able to find one that you know should have disappeared. Otherwise, you'll have to select one at random. You can now look at the objects that reference this instance by inspecting `self allOwners` in the Inspector window. This is the classic approach, but it's not easy to use this technique to follow through the owners. A better approach is to inspect the following in the Inspector window.

`self allOwnersWeakly: true`

Sending `allOwnersWeakly: true` to an object returns a `WeakArray` of references rather than an `Array`, which means that the references can be garbage collected. Using `allOwnersWeakly:` usually gives you a smaller list of owners to look at. Below is some code that you can add to `Inspector` to inspect owners of an object, filtering out most of the uninteresting owners. It is based on a method written by Jan Steinman and documented by Alan Knight in The Smalltalk Report, May 1994. It appears to work, but I don't use it enough to guarantee anything!

`Inspector>>inspectOwners`
((self fieldValue allOwnersWeakly: true) reject: [:each | self shouldReject: each]) inspect

Inspector>>shouldReject: anObject
"The WeakArray often gives an owner of 0"
anObject == 0 ifTrue: [^true].
"We don't want to see the object we are inspecting"
anObject == object ifTrue: [^true].
"We don't want to see this inspector"
anObject == self ifTrue: [^true].
"We don't want to see the methods that got us here"
(anObject class == MethodContext
and: [anObject selector == #allOwners
or: [anObject selector == #allOwnersWeakly:]]) ifTrue: [^true].
"We don't want to see the stack array that contains the object"
(anObject class == Array
and: [anObject size == 12
and: [(anObject at: 3) == self fieldValue]]) ifTrue: [^true].
"We want to see anything that's left after this filter"
^false

The Advanced Tools contains a class, *ReferencePathCollector*, whose purpose is to help find objects that are not being garbage collected. The class comment includes the following: "My purpose is to find what is hanging onto objects that can't be garbage collected, by finding reference paths to a given object." We can add another item to the inspect menu that uses the ReferencePathCollector. When you use it, be prepared for a long path; it can be several hundred references long.

Inspector>>inspectPaths
(ReferencePathCollector allReferencePathsTo: self fieldValue)
inspect

Once you've added these methods, you'll need to go to the `fieldMenu` method of `Inspector` and add the methods `inspectOwners` and `inspectPaths` to the menu. The labels string should now look something like `'inspect\owners\paths' withCRs`. Accept the method then evaluate `Inspector flushMenus` to make the change take effect. Here's a few lines of code from the modified `fieldMenu`.

ListMenu == nil ifTrue:
[ListMenu := Menu
labels: 'inspect\owners\paths' withCRs
values: #(inspectField inspectOwners inspectPaths)].

For additional information on objects not being reclaimed, you might look at the article *Taking Out The Garbage*, by Derek Williams, in the January 1996 issue of The Smalltalk Report.

## Public Domain debugging software

There is a debugging enhancement available from the Smalltalk Archives, written by Bob Hinkle. Called *Breakpoint*, its great virtue is that it allows you to add and remove breakpoints without affecting the change set and change log. You can add either an absolute breakpoint, which always causes a halt when encountered, or a conditional breakpoint, which only causes a halt when the associated condition evaluates to *true*. A companion package, *Lightweight*, also written by Hinkle, allows you to add breakpoints to individual objects, rather than all objects of that class. If you can modify the behavior of just the one object without affecting the behavior of any
other object. There is more information on how to get files from the Smalltalk Archives in Chapter 35, Public Domain Code and Information.

# Commercial debugging software

## The Smalltalk Professional Debug Package

Also available for use with Objectworks\Smalltalk and VisualWorks is the *Smalltalk Professional Debug Package*. As with *Breakpoint*, adding a breakpoint does not affect the change set or the change log. However, where *Breakpoint* uses the compiler to add breakpoints, the *Smalltalk Professional Debug Package* modifies the compiled code directly. This provides the capability for some nice features such as the ability to add another breakpoint to a method without having to restart the method, having the breakpoints disappear when the method exits, and allowing skip-to-caret into and out of blocks. You can also use the package to add debugging code that does not cause a halt; for example to just collect data.

At the time of writing, the software cost is $89.00 plus shipping and handling ($149 for the ENVY version).
To order or get additional information, you can send e-mail to traymond@pcix.com, or call Terry Raymond at (401) 846-6573. He also has a web site at http://www2.pcix.com/~traymond/ where you can get more information.

## Object Explorer

Another package that might help you debug an application is *Object Explorer* from First Class Software. This software diagrams the inter-relationships between objects, which can be quite a help when debugging a complex application that you are not familiar with. There is a review of *Object Explorer* by Steven Bilow in the June 1994 issue of *The Journal of Object-Oriented Programming*, which speaks very highly of the product—"It is a profound debugging tool and a great design aid."

At the time of writing, the software cost is $499. You can reach First Class Software at P.O. Box 226, Boulder Creek, CA 95006-0226, at (408) 338-4649, or by e-mail to Compuserve address 70761.1216@compuserve.com.
22

Common Errors

This chapter describes some of the more common errors that Smalltalk programmers make and gives
suggestions on how to prevent the errors.

Notifier window messages

As you test your code you are likely to have exceptions raised. Here are a few exception messages you may
run into, along with some text describing common causes of the exception.

Message not understood: #self (or some other object)

This occurs when you leave a period off the end of a statement. It tells you that the *self* with which you are
starting a statement is being used as a message to the result of the previous statement. Ie, there is no statement
separator. You may be sending the message to an object other than self, in which case that variable name will be
the message name that was not understood.

Message not understood: #do:

This often occurs in a `printOn:` method, if the parameter to `nextPutAll:` is not a string. To correct this, send `printString` or `displayString` to the parameter, or use the `print:` message instead of `nextPutAll`:

Message not understood: #startingAt:replaceElementsIn:from:to:

This often occurs when you are creating a string using the comma (`,` ) message but the object on the right side
of the comma is not of the appropriate class. For example, 'abc', 3 would generate this exception.

Message not understood: #someArbitraryMessage

The most common cause of getting a message not understood exception is to send the message to `nil`. Ie, your
variable contains `nil` rather than the object you thought it contained.
## Losing code you modified in a debugger

A common mistake when debugging is to add `self halt` to a method, and leave the method displayed in a Browser window. When you hit the halt, you step through the code, find the problem, and modify the code in the debugger. You then go back to the original window and make another change to the method. Since the Browser is still looking at the old version of the code, you lose the changes you made in the debugger. The easiest way to correct this problem is to deselect the method after adding a `self halt`. Then when you select it again, it has the changes.

## Removing from a collection you are iterating over

If you are iterating over a collection using `do:`, and removing elements that satisfy some condition, you will probably get an exception. The invocation of `do:` sets up some boundary conditions which are no longer true when elements are removed because the collection will be rearranged as you remove elements. When I do the following, I get a "Message not understood" exception.

```python
collection:= OrderedCollection withAll: #(1 2 3 4 5 6).
collection do: [ :each | each even ifTrue: [collection remove: each]].
```

Instead, make a copy of the collection before iterating over it, such as shown below (of course, you should also consider using `select:` or `reject:`).

```python
collection:= OrderedCollection withAll: #(1 2 3 4 5 6).
collection copy do: [ :each | each even ifTrue: [collection remove: each]].
```

It's also possible to have the same problem even if you are not deleting objects directly. For example, the following code closes any open files with the specified path. As the files are closed, they are removed from the `OpenStreams` collection of `ExternalStream`, so again, we need to iterate over a copy of the collection.

```python
(ExternalStream classPool at: #OpenStreams) copy
do: [ :each | each name = aPath ifTrue: [each close]].
```

## Not returning the injection variable in `inject:into`:

If you use `inject:into:`, you'll probably find that you sometimes forget to return the thing that is being injected. Remember that the value of a block is the value of the last statement executed, so you need to finish with something that guarantees the last thing is the injection variable. You can simply name the injection variable, or you can send it the `yourself` message. Here are examples of both.

```python
self withAllSubclasses
inject: OrderedCollection new
into: [:coll :each | coll addAll: each allInstances; yourself]

#(3 $x 'hello' #mySymbol)
inject: String new writeStream
into: [ :stream :each |
       stream print: each class; nextPutAll: ' value '; print: each;
]

stream]
```
## Missing ^

A very common bug for new Smalltalk programmers is to forget the caret (^) when returning a value. This is usually seen when writing a new method. For example, the following creates a new, initialized instance of MyClass, then returns the class rather than the instance.

```
MyClass>>new
    super new initialize
```

The correct version should have a caret to return the instance. (It might also be worth using the `basicNew:` message — see Chapter 5, Instance Creation for more information.)

```
MyClass>>new
    ^super new initialize
```

```
MyClass>>new
    ^self basicNew initialize.
```

## Not implementing =

If you create your own class then compare two instances of it using `=`, the test will return false. For example, two separately created instances of a new `Location` class will not compare as equal, even if all the details of the location are the same. This is because the default implementation of `=` is to use `==`, so `=` is actually checking to see if they are the *same object*. If you create your own class and will be doing tests for equality between instances of the class, you need to write your own `=` method that compares the instance variables.

If you write your own `=` method, you will also need to write your own `hash` method, since two objects that are equal should also have the same hash value. (Hash values are used when putting objects in collections that use hashing, such as `Set` and `Bag`.)

## Assuming that messages return self

A common bug is to assume that all methods return `self`, and in particular, to assume that `add`: returns `self`. The following will *not* give you what you expect, because `add`: returns the object added (similarly `remove`: returns the object removed, and `at:put`: returns the object put).

```
collection := OrderedCollection new
    add: objectOne;
    add: objectTwo.
```

The example above actually assigns `objectTwo` to `collection`. The following techniques all give you what you expected.

```
collection := OrderedCollection new.
collection
    add: objectOne;
    add: objectTwo.

.collection := OrderedCollection new
    add: objectOne;
    add: objectTwo.
```