3. Objects like `Closure` or `Context` that have both named instance variables and indexed instance variables. In the object, the indexed instance variables follow the named instance variables.

4. Objects like `ByteString` or `Bitmap` that have indexed instance variables numbered from 1 to N that contain raw data. Each datum may occupy 8, 16 or 32-bits, depending on its class definition. The data can be accessed as either integers, characters or floating-point numbers, depending on how methods `at:` and `at:put:` are implemented. The `at:` and `at:put:` methods convert between Pharo objects and raw data, hiding the internal representation, but allowing the system to represent efficiently data such as strings, and bitmaps.

A beauty of Pharo is that you normally don't need to care about the differences between these three kinds of object.

## 6.11 Chapter summary

The object model of Pharo is both simple and uniform. Everything is an object, and pretty much everything happens by sending messages.

* Everything is an object. Primitive entities like integers are objects, but also classes are first-class objects.

* Every object is an instance of a class. Classes define the structure of their instances via *private* instance variables and the behaviour of their instances via *public* methods. Each class is the unique instance of its metaclass. Class variables are private variables shared by the class and all the instances of the class. Classes cannot directly access instance variables of their instances, and instances cannot access instance variables of their class. Accessors must be defined if this is needed.

* Every class has a superclass. The root of the single inheritance hierarchy is `ProtoObject`. Classes you define, however, should normally inherit from `Object` or its subclasses. There is no syntax for defining abstract classes. An abstract class is simply a class with an abstract method (one whose implementation consists of the expression `self subclassResponsibility`). Although Pharo supports only single inheritance, it is easy to share implementations of methods by packaging them as *traits*.

* Everything happens by sending messages. We do not *call methods*, we *send messages*. The receiver then chooses its own method for responding to the message.

* Method lookup follows the inheritance chain; `self` sends are dynamic and start the method lookup in the class of the receiver, whereas `super` sends start the method lookup in the superclass of `class` in which the `super` send is written. From this perspective `super` sends are more static than `self` sends.
* There are three kinds of shared variables. Global variables are accessible everywhere in the system. Class variables are shared between a class, its subclasses and its instances. Pool variables are shared between a selected set of classes. You should avoid shared variables as much as possible.
<figure><img src="image_66.png" /></figure>
CHAPTER 7

Some of the key tools of the
Pharo environment

The goal of this chapter is to present the main tools of the Pharo programming environment. You have already seen how to define methods and classes using the browser; this chapter will show you more of its features, and introduce you to some of the other browsers.

Of course, very occasionally you may find that your program does not work as you expect. Pharo has an excellent debugger, but like most powerful tools, it can be confusing on first use. We will walk you through a debugging session and demonstrate some of the features of the debugger.

One of the unique features of Pharo (and its ancestors) is that while you are programming, you are living in a world of live objects, not in a world of static program text. This makes it possible to get very rapid feedback while programming, which makes you more productive. There is a tool that let you look at, and indeed change, live objects: the *inspector*.

7.1 Pharo environment overview

The System Browser is the central development tool. You will use it to create, define, and organize your classes and methods. Using it you can also navigate through all the library classes. Unlike other environments where the source code is stored in separate files, in Pharo all classes and methods are contained in the image.

The Finder tool will let you find methods, classes, pragmas, and more. You
can look for a method's name, a class name, some source code, a pragma's
name or even look for methods by providing an example!

The Monticello Browser is the starting point for loading code from, and saving code in, Monticello packages. It is discussed in more detail in Chapter : Sharing Code and Source Control.

The Process Browser provides a view of all of the processes (threads) executing in Smalltalk.

The Test Runner lets you run and debug SUnit tests, and is described in more detail in Chapter : SUnit.

The Transcript is a window on the Transcript output stream, which is useful for writing log messages.

The Playground is a window into which you can type input. It can be used for any purpose, but is most often used for typing Pharo expressions and executing them via Do it. We have already briefly encountered the Playground (and the Transcript) in Chapter : A Quick Tour of Pharo.

The Debugger has an obvious role, but you will discover that it has a more central place compared to debuggers for other programming languages, because in Pharo you can *program* in the debugger. The debugger is not launched from a menu; it is normally entered by running a failing test, by typing `CMD-` to interrupt a running process, or by inserting a `Halt` now expression in code.

## Window groups

Managing multiple windows within a Pharo image can become a tedious process. Window Groups are windows that offer tab support similar to the one you are used to on your web browser. To create a window group, click on the down arrow which appears on the top right corner of every window within Pharo, and select Create window group. This will turn that window into a window group with a tab bar, containing as its first tab the original contents of the window. You can add other windows to the group (within the Pharo image only, of course), by dragging and dropping their title bars onto the tab bar, next to existing tabs. Each new window that you drag onto the tab bar will be added as a new tab.

## Themes and icon sets

If, like some of us, you are not a fan of the default bright theme, there is also a dark theme that can be used with Pharo. It can be found in the Settings browser in the World Menu (World > System > Settings), in the Appearance section. The User interface theme pulldown allows you to switch between the default Pharo3 theme and the Pharo3 Dark theme. You can also experiment with available icon sets in the next pulldown in that section.

Please note that you may have to close and reopen existing windows to redraw them correctly with the new dark theme.
<figure><img src="image_67.png" /><figcaption>**Figure 7.1:** Window Group with two tabs, one with Playground and one with System Browser</figcaption></figure>

You can use the Catalog Browser to install additional themes. Open World > Tools > Catalog Browser and search for theme in the search box. For example, if you want something more colorful, you can download the Nireas theme, which is a blue theme inspired by classic home computers like Amiga 500 and Amstrad CPC 6128. Nireas comes with a GUI tool that allows you to customize the theme's colors to your liking, if blue is not your thing.

Of course, if you are feeling especially adventurous, you can even make your own themes using existing ones as templates.

## 7.2 The main code browser

Many different class browsers have been developed over the years for Pharo. Pharo simplifies this story by offering a single browser that integrates various views. Figure 7.2 shows the browser as it appears when you first open it.

The four small panes at the top of the browser represent a hierarchic view of the methods in the system, much in the same way as the Mac OS X Finder in column mode provide a view of the files on the disk. The leftmost pane lists *packages* of classes; select one (say *Kernel*) and the pane immediately to the right will then show all of the classes in that package.

Similarly, if you select one of the classes in the second pane, say, *Boolean* (see Figure 7.3), the third pane will show all of the *protocols* defined for that class, as well as a virtual protocol `--all--`. Protocols are a way of categorizing methods; they make it easier to find and think about the behaviour of a class by breaking it up into smaller, conceptually coherent pieces. The fourth pane shows the names of all of the methods defined in the selected protocol. If you then select a method name, the source code of the corresponding method
<figure><img src="image_68.png" /><figcaption>Figure 7.2: The main code browser.</figcaption></figure>

<figure><img src="image_69.png" /><figcaption>Figure 7.3: The browser with the class Boolean selected.</figcaption></figure>
## 7.2 The main code browser

<figure><img src="image_70.png" /><figcaption>Figure 7.4: Browsing the or: method in class Boolean.</figcaption></figure>

appears in the large pane at the bottom of the browser, where you can view it, edit it, and save the edited version. If you select class Boolean, protocol controlling and the method or:, the browser should look like Figure 7.4.

Unlike directories in a file browser, the four top panes of the browser are not quite equal. Whereas classes and methods are part of the Smalltalk language, packages and protocols are not: they are a convenience introduced by the browser to limit the amount of information that needs to be shown in each pane. For example, if there were no protocols, the browser would have to show a list of all of the methods in the selected class; for many classes this list would be too large to navigate conveniently.

Because of this, the way that you create a new package or a new protocol is different from the way that you create a new class or a new method. To create a new package, right-click in the package pane and select Add package.... To create a new protocol, right-click in the protocol pane and select Add protocol.... Enter the name of the new thing in the dialog, and you are done: there is nothing more to a package or a protocol than its name and its contents.

In contrast, to create a new class or a new method, you will actually have to write some Smalltalk code. If you click the currently selected package (in the left-most pane), the bottom browser pane will display a class creation
<figure><img src="image_71.png" /><figcaption>Figure 7.5: Browser showing the class-creation template</figcaption></figure>

template (Figure 7.5). You create a new class by editing this template: replace `Object` by the name of the existing class of which you wish to create a subclass, replace `NameOfSubclass` by the name that you would like to give to your new subclass, and fill in the instance variable names if you know them. The package for the new class is by default the currently selected package, but you can change this too if you like. If you already have the browser focused on the class that you wish to subclass, you can get the same template with slightly different initialization by right-clicking in the class pane, and selecting `Add Class`. You can also just edit the definition of an existing class, changing the class name to something new. In all cases, when you accept the new definition, the new class (the one whose name follows the `#`) is created (as is the corresponding metaclass). Creating a class also creates a global variable that references the class, which is why you can refer to all of the existing classes by using their names.

Can you see why the name of the new class has to appear as a `Symbol` (i.e., prefixed with `#`) in the class creation template, but after the class is created, code can refer to the class by using the name as an identifier (without the `#`?)

The process of creating a new method is similar. First select the class in which you want the method to live, and then select a protocol. The browser will display a method-creation template, as shown in Figure 7.6, which you can fill-in or edit.
## 7.2 The main code browser

<figure><img src="image_72.png" /><figcaption>Figure 7.6: Showing the method-creation template.</figcaption></figure>

### Navigating the code space

The browser provides several tools for exploring and analyzing code. These tools can be accessed by right-clicking in the various contextual menus, or, in the case of the most frequently used tools, by means of keyboard shortcuts.

#### Opening a new browser window

Sometimes you want to open multiple browser windows. When you are writing code you will almost certainly need at least two: one for the method that you are typing, and another to browse around the system to see how things work. You can open a browser on a class named by any selected text using the CMD-b keyboard shortcut.

**To do** Try this: In a playground window, type the name of a class (for instance `Morph`), select it, and then press `CMD-b`. This trick is often useful; it works in any text window.

#### Message senders

While writing new code, refactoring existing code, or while trying to learn how to use unfamiliar libraries, you will frequently want to know the senders
<figure><img src="image_73.png" /><figcaption>Figure 7.7: The Senders Of... (b,n) menu item.</figcaption></figure>

and implementors of various messages.

There are several ways of discovering where in the codebase a message is used, by listing its senders:

1. **From the method pane.** Select a method in the method pane of the browser. You can then right-click on it and select Senders of... (b,n) in the context menu. Alternatively, you can also use the shortcut CMD-b CMD-n to do the same thing (that's what the b, n in the menu item stands for). To help remember this shortcut, think: browse senders.

2. **From the code pane.** Highlight a particular message in the source code. This can be done in a code pane of a browser, in a Playground window, or in any text window. If you want to find the senders of a keyword message, you highlight all of the keywords in the message, including arguments. Then, you can right-click on the highlighted selector and choose Code search... > senders of it (n). Alternatively, you can use the shortcut CMD-n instead of right-clicking.

3. **Using Spotter.** Bring up a particular method in Spotter (press SHIFT-Enter to bring up the Spotter search box, type in the message selector, arrow down to a particular Implementor of that message, and press CMD-right arrow to focus the search on it.) A list of Senders now appears in the search results.
7.2 The main code browser

<figure><img src="image_74.png" /><figcaption>**Figure 7.8:** The Senders Browser showing that the `Canvas>>draw` method sends the `drawOn:` message to its argument.</figcaption></figure>

Only a handful of senders are shown by default, but you can view the full list by clicking on the arrow next to the Senders category (or arrow down to the Senders list and expand it by pressing `CMD-SHIFT-right arrow`).

Let's try some of these in action.

Open a browser on the `Morph` class, select the `Morph>>drawOn:` method in the method pane. If you now press `CMD-b CMD-n` (or right-click in the method pane and select Senders of ... (Figure 7.7)), a browser will open with the list of all methods in the image that send the selected message (Figure 7.8).

Now look at the third sender on the list, `Canvas>>draw:`. You can see that this method sends `drawOn:` to whatever object is passed to it as an argument, which could potentially be an instance of any class at all. Dataflow analysis can help figure out the class of the receiver of some messages, but in general, there is no simple way for the browser to know which message-sends might cause which methods to be executed. For this reason, the Senders browser shows exactly what its name suggests: all of the senders of the message with the chosen selector. The senders browser is nevertheless extremely useful when you need to understand how you can use a method: it lets you navigate quickly through example uses. Since all of the methods with the same selector
tors category will show up in the search results, showing the first handful of implementors. To see the full list, click on the arrow to the right of Implementors category (or arrow down to Implementors and press `SHIFT-CMD-right arrow`).

Try this out: Press `SHIFT-Enter` and type `drawOn:` in the Spotter search box. You should see a list showing 5 out of 100 implementors of that method. It shouldn't be all that surprising that so many classes implement this method: `drawOn:` is the message that is understood by every object that is capable of drawing itself on the screen.

Notice that if you only typed `drawOn` and left out the colon (`:`), the number of implementors in the search results is larger. This is because Spotter is doing a partial search, and including any methods that have `drawOn` in the name, such as `drawOn:offset:`, `drawOnAthensCanvas:`, and so on. This is useful for when you want to find a method but can only remember a part of its name.

## Method inheritance and overriding

The inheritance browser displays all the methods overridden by the displayed method. To see how it works, select the `ImageMorph>>drawOn:` method in the browser. Note the arrow icons next to the method name (Figure 7.10). The upward-pointing arrow tells you that `ImageMorph>>drawOn:` overrides an inherited method (i.e., `Morph>>drawOn:`), and the downward-pointing arrow tells you that it is overridden by subclasses. (You can also click on the icons to navigate to these methods.) Now right-click on it in the method pane, and select `Inheritance`. The inheritance browser shows you the hierarchy of overridden methods (see Figure 7.10).

## Hierarchy view

By default, the browser presents a list of packages in the leftmost pane. However it is possible to switch to a class hierarchy view. Simply select a particular class of interest, such as `ImageMorph` and then click on the `Hierarchy` button (`Hier.`). You will then see in the second pane a class hierarchy displaying all superclasses and subclasses of the selected class.

Notice that the package pane is disabled, and the packages are greyed out. When you are in `Hierarchy` view, you cannot change packages. To be able to change them again, toggle out of the `Hierarchy` view by clicking on the `Hierarchy` button again.

In Figure 7.11, the hierarchy view reveals that the direct superclass of `ImageMorph` is `Morph`.
<figure><img src="image_75.png" /><figcaption>Figure 7.10: ImageMorph>>drawOn: and the hierarchy of classes overriding it.</figcaption></figure>

## Finding variable references

By right-clicking on a class in the class pane, and selecting Analyze > Inst var references... or Analyze > Class var refs..., you can find out where an instance variable or a class variable is used. You can also have access to those views by clicking on the Variables button, above the package list. Once you click on the button or select the menu item, you will be presented with a dialog that invites you to choose a variable from all of the variables defined in the current class, and all of the variables that it inherits. The list is in inheritance order; it can often be useful to bring up this list just to remind yourself of the name of an instance variable. If you click outside the list, it will go away and no variable browser will be created. If you click on a variable, bounds for example, a Message Browser will be created (Figure 7.12).

You can use a similar method to look at direct variable assignments (that is, places that modify the variable without using accessor methods). Right-click on the class and select Analyze > Inst var assignments.
## 7.2 The main code browser

<figure><img src="image_76.png" /><figcaption>Figure 7.11: A hierarchy view of ImageMorph.</figcaption></figure>

### Bytecode source

You have the possibility of browsing the bytecode of a method. To do that, right-click on your method and select **Toggle Bytecodes**, or use the shortcut `CMD-b CMD-b` (see Figure 7.13). Reselect the method again to get back to the normal view.

### Refactorings

The contextual menus offer a large number of standard refactorings. Simply right-click in any of the four panes to see the currently available refactoring operations. See Figure 7.14.

Refactoring was formerly available only in a special browser called the refactoring browser, but it can now be accessed from any browser.

### Browser menus

Many additional functions are available by right-clicking in the browser panes. Even if the labels on the menu items are the same, their meaning may be context dependent. For example, the package pane, the class pane, the protocol pane and the method pane all have a **File** out menu item. However, they do different things: the package pane's **File** out menu item files out the
<figure><img src="image_77.png" /><figcaption>**Figure 7.12:** A Message Browser for accesses to bounds variable of Morph.</figcaption></figure>

whole package, the class pane's item files out the whole class, the protocol pane's item files out the whole protocol, and the method pane's item files out just the displayed method.

Although this may seem obvious, it can be a source of confusion for beginners.

Possibly the most useful menu item is `Find class... (f, c)` in the package or class panes. Most of us do not know the package contents of the whole system, and it is much faster to type `CMD-f CMD-c` followed by the first few characters of the name of a class than to guess which package it might be in.

The History Navigator pulldown, found above the protocol and method panes, can also help you quickly go back to a class or method that you have browsed recently, even if you have forgotten its name.

Another useful method in the class pane is `Find method (CMD-f CMD-m)`, which brings up a menu of all the methods in the class and gives you a search box.

Alternatively, if you are searching for a particular method of the selected class, it is often quicker to browse the `--all` protocol, place the mouse in the method pane, and type the first letter of the name of the method that you are looking for. This will usually scroll the pane so that the sought-for method
<figure><img src="image_78.png" /><figcaption>Figure 7.13: Bytecode of the ImageMorph#DrawOn: compiled method.</figcaption></figure>

<figure><img src="image_79.png" /><figcaption>Figure 7.14: Refactoring operations.</figcaption></figure>
name is visible.

**To do** Try both ways of navigating to OrderedCollection>>removeAt:

There are many other options available in the menus. It pays to spend a few minutes working with the browser and seeing what is there.

## Browsing programmatically

The class SystemNavigation provides a number of utility methods that are useful for navigating around the system. Many of the functions offered by the system browser are implemented by SystemNavigation.

Open a playground and evaluate the following code to browse the senders of drawOn::

```
SystemNavigation default browseAllSendersOf: #drawOn:
```

To restrict the search for senders to the methods of a specific class:

```
SystemNavigation default browseAllSendersOf: #drawOn: localTo:
ImageMorph
```

Because the development tools are objects, they are completely accessible from programs and you can develop your own tools or adapt the existing tools to your needs.

The programmatic equivalent to the Implementors of... menu item is:

```
SystemNavigation default browseAllImplementorsOf: #drawOn:
```

**To do** To learn more about what is available, explore the class SystemNavigation

with the browser.

## 7.3 The inspector

One of the things that makes Pharo so different from many other programming environments is that it provides you with a window onto a world of live objects, not a world of static code. Any of those objects can be examined by the programmer, and even modified (although some care is necessary when changing the basic objects that support the system). By all means experiment, but save your image first!

As an illustration of what you can do with an inspector, type DateTime now in a playground, and then right-click and choose Inspect it (CMD-i) or Do it and go (CMD-g) (the latter opens an inspector inside the playground window).
<figure><img src="image_80.png" /><figcaption>**Figure 7.15:** Inspecting `DateAndTime` now.</figcaption></figure>

Note that it's often not necessary to select the text before using the menu; if no text is selected, the menu operations work on the whole of the current line.

A window like that shown in Figure 7.15 will appear. This is an inspector, and can be thought of as a window onto the internals of a particular object – in this case, the particular instance of `DateAndTime` that was created when you evaluated the expression `DateAndTime` now. The title bar of the window shows the printable representation of the object that is being inspected.

In the default view (the Raw tab), instance variables can be explored by selecting them in the variable list in the Variable column. As you select a variable, its printable representation is shown in the Value column. More importantly, a separate Inspector view for the selected variable opens in the right hand pane.

For variables that are simple types (booleans, integers, etc), the nested inspector view is not much different from the printable representation in the Value column (although it is a full-fledged Inspector). But for most instance variables, the nested Inspector view on the right has its own Raw tab, with its own list of instance variables. (You can also see that list in the left pane, by expanding the triangle next to a variable's name.)

You can keep drilling down into the hierarchy of instance variables, with more nested Inspector panes opening to the right of the parent. However, to prevent the multiple panes from being impractical, the panes "scroll" to the right, within the overall inspector window. You can keep track of
which "page" you're on, and also back-track to the original instance that you
were inspecting, by using the pagination dots at the bottom of the inspector
window.

There are special variants of the inspector for Dictionaries, OrderedCollec-
tions, CompiledMethods and a few other classes. These variants have other
tabs, in addition to the Raw view, that make it easier to examine the contents
of these special objects. For example, an inspector on a Dictionary instance,
has an additional Items tab that shows that dictionary's keys and values in an
intuitive fashion.

The horizontal pane at the bottom of the inspector is a small playground
window. It is useful because in this window, the pseudo-variable self is bound
to the object that you have selected in the left pane. That means you can write
and evaluate arbitrary code expressions that use the selected variable's self,
in that bottom pane.

For example, take the inspector on `DateTime` now that you opened earlier
in this section. You can select its bottom playground pane, and evaluate the
expression `self - DateTime today`. The result will be a `Duration` object
that represents the time interval between midnight today and the instant
at which you evaluated `DateTime` now and created the `DateTime` instance
that you are inspecting. You can also try evaluating `DateTime` now
- `self`; this will tell you how long you have spent reading this section of this
book!

The bottom pane is especially useful if you wanted to change the instance
variables of the object being inspected. Provided that you have accessor
methods defined for those variables, you can send messages to the root self
and change its variables via those accessor methods.

## 7.4 The debugger

The debugger is arguably the most powerful tool in the Pharo tool suite. It is
used not just for debugging, but also for writing new code. To demonstrate the
dibugger, let's start by creating a bug!

Using the browser, add the following method to the class `String`:

```
suffix
    "assumes that I'm a file name, and answers my suffix, the part after
    the last dot"

| dot dotPosition |
dot := '.'.
dotPosition := (self size to: 1 by: -1) detect: [ :i | (self at: i)
    = dot ].
^ self copyFrom: dotPosition to: self size
```
<figure><img src="image_81.png" /><figcaption>Figure 7.16: A PreDebugWindow notifies us of a bug.</figcaption></figure>

Of course, we are sure that such a trivial method will work, so instead of writing an SUnit test, we just type `'readme.txt'` suffix in a playground and Print it (p). What a surprise! Instead of getting the expected answer `'txt'`, a PreDebugWindow pops up, as shown in Figure 7.16.

The PreDebugWindow has a title bar that tells us what error occurred, and shows us a *stack trace* of the messages that led up to the error. Starting from the bottom of the trace, `UndefinedObject>>DoIt` represents the code that was compiled and run when we selected `'readme.txt'` suffix in the playground and asked Pharo to Print it. This code, of course, sent the message suffix to a `ByteString` object (`'readme.txt'`). This caused the inherited suffix method in class `String` to execute; all this information is encoded in the next line of the stack trace, `ByteString(String)>>suffix`. Working up the stack, we can see that suffix sent `detect:...` and eventually `detect:ifNone sent errorNotFound:.`.

To find out why the dot was not found, we need the debugger itself, so click on Debug. You can also open the debugger by clicking on any of the lines on the stack trace. If you do this, the debugger will open already focused on the corresponding method.

The debugger is shown in Figure 7.17; it looks intimidating at first, but it is quite easy to use. The title bar and the top pane are very similar to those that we saw in the PreDebugWindow. However, the debugger combines the stack trace with a method browser, so when you select a line in the stack trace, the corresponding method is shown in the pane below. It's important to realize that the execution that caused the error is still in your image, but in a suspended state. Each line of the stack trace represents a frame on the
<figure><img src="image_82.png" /><figcaption>**Figure 7.17:** The debugger showing the execution stack and the state of various objects.</figcaption></figure>

execution stack that contains all of the information necessary to continue the execution. This includes all of the objects involved in the computation, with their instance variables, and all of the temporary variables of the executing methods.

In Figure 7.17 we have selected the `detect:ifFound:ifNone:` method in the top pane. The method body is displayed in the center pane; the blue highlight around the message value shows that the current method has sent the message value and is waiting for an answer.

The *Variables* pane at the bottom of the debugger is actually like an *inspector* (without *playground* pane). You can select one variable and open another inspector pane with the well-known inspector panes (`Raw`, `...`), and an *Evaluator* acting as a *Playground* for evaluating code within the context of the selected variable. The variables list has up to four types variables it shows.

* **parameter** any parameter passed to this method.

* **temp** any temporaries used in this method.

* **attribute** any instance variable accessible from the context of the current receiver.

* **implicit** pseudo variables (`self`, `thisContext`, `stackTop`) used in the
current context.

As you select different stack frames, the identity of self may change, and
so will the contents of the Variables list. If you click on self in the bottom-
left pane, you will see that self is the interval (10 to: 1 by -1), which is
what we expect. You can always select self and select the Evaluator pane to
evaluate some code in the content of the current receiver. But because all of
the variables are also in scope in the method pane; you should feel free to type
or select expressions directly in the method pane and evaluate them. You can
always Cancel (l) your changes using the menu or CMD-l.

Selecting thisContext from the list of (implicit) variables, shows the current context object.

As we can see one method lower in the stack trace, the exceptionBlock is
[self errorNotFound: ...], so, it is not surprising that we see the corre-
sponding error message.

Incidentally, if you want to open a full inspector on one of the variables shown
in the mini-inspectors, just double-click on the name of the variable, or select
the name of the variable and right-click to choose Inspect (i). This can be
useful if you want to watch how a variable changes while you execute other
code.

Looking back at the method window, we see that we expected the penultimate
line of the method to find '.' in the string 'readme.txt', and that execution
should never have reached the final line. Pharo does not let us run an execu-
tion backwards, but it does let us start a method again, which works very well
in code that does not mutate objects, but instead creates new ones.

Click Restart, and you will see that the focus of execution returns to the first
statement of the current method. The blue highlight shows that the next
message to be sent will be do: (see Figure 7.18).

The Into and Over buttons give us two different ways to step through the
execution. If you click Over, Pharo executes the current message-send (in
this case the do:) in one step, unless there is an error. So Over will take us to
the next message-send in the current method, which is value - this is exactly
where we started, and not much help. What we need to do is to find out why
the do: is not finding the character that we are looking for.

After clicking Over, click Restart to get back to the situation shown in Figure
7.18.

Click Into two times; Pharo will go into the method corresponding to the
highlighted message-send, in this case, Interval>>do:.

However, it turns out that this is not much help either; we can be fairly con-
fident that Interval>>do: is not broken. The bug is much more likely to be
in what we asked Pharo to do. Through is the appropriate button to use in this
<figure><img src="image_83.png" /><figcaption>**Figure 7.18:** The debugger after restarting the `detect:ifFound:IfNone:` method.</figcaption></figure>

case: we want to ignore the details of the `do:` itself and focus on the execution of the argument block.

Select the `detect:ifFound:IfNone:` method again and `Restart` to get back to the state shown in Figure 7.18. Now click on `Through` a few times. Select each in the context window as you do so. You should see each count down from 10 as the `do:` method executes.

When each is 7 we expect the `ifTrue:` block to be executed, but it isn't. To see what is going wrong, go to `Into` the execution of `value:` as illustrated in Figure 7.19.

After clicking `Into`, we find ourselves in the position shown in Figure 7.20. It looks at first that we have gone back to the suffix method, but this is because we are now executing the block that suffix provided as argument to `detect:`.

If you select `dot` in the context inspector, you will see that its value is `'. .'`. And now you see why they are not equal: the seventh character of `'readme.txt'`
<figure><img src="image_84.png" /><figcaption>Figure 7.19: The debugger after stepping through the `do:` method several times.</figcaption></figure>

is of course a `Character`, while `dot` is a `String`.

Now that we see the bug, the fix is obvious: we have to convert `dot` to a character before starting to search for it.

Change the code right in the debugger so that the assignment reads `dot := $.` and accept the change.

Because we are executing code inside a block that is inside a `detect:`, several stack frames will have to be abandoned in order to make this change. Pharo asks us if this is what we want (see Figure 7.21), and, assuming that we click `yes`, will save (and compile) the new method.

The evaluation of the expression `'readme.txt'` suffix will complete, and print the answer `.txt`.

Is the answer correct? Unfortunately, we can't say for sure. Should the suffix be `.txt` or `.txt`? The method comment in `suffix` is not very precise. The way to avoid this sort of problem is to write an `SUnit` test that defines the answer.
<figure><img src="image_85.png" /><figcaption>Figure 7.20: The debugger showing why 'readme.txt' at: 7 is not equal to dot.</figcaption></figure>

```
testSuffixFound
    self assert: 'readme.txt' suffix = 'txt'
```

The effort required to do that was little more than to run the same test in the playground, but using SUnit saves the test as executable documentation, and makes it easy for others to run. Moreover, if you add `testSuffix` to the class `StringTest` and run that test suite with SUnit, you can very quickly get back to debugging the error. SUnit opens the debugger on the failing assertion, but you need only go back down the stack one frame, Restart the test and go into the `suffix` method, and you can correct the error, as we are doing in Figure 7.22. It is then only a second of work to click on the Run Failures button in the SUnit Test Runner, and confirm that the test now passes.

Here is a better test:

```
testSuffixFound
    self assert: 'readme.txt' suffix = 'txt'.
    self assert: 'read.me.txt' suffix = 'txt'
```
7.4 The debugger

<figure><img src="image_86.png" /><figcaption>**Figure 7.21:** Changing the suffix method in the debugger: asking for confirmation of the exit from an inner block.</figcaption></figure>

Why is this test better? Because it tells the reader what the method should do if there is more than one dot in the target String.

There are a few other ways to get into the debugger in addition to catching errors and assertion failures. If you execute code that goes into an infinite loop, you can interrupt it and open a debugger on the computation by typing `CMD-`. (that's a full stop or a period, depending on where you learned English). (It is also useful to know that you can bring up an emergency debugger at any time by typing `CMD-SHIFT-`.) You can also just edit the suspect code to insert `Halt now..` So, for example, we might edit the suffix method to read as follows:

```
suffix
  "assumes that I'm a file name, and answers my suffix, the part after
   the last dot"

  | dot dotPosition |
  dot := FileDirectory dot first.
  dotPosition := (self size to: 1 by: -1) detect: [ :i | (self at: i)
   = dot ].

  Halt now.
  ^ self copyFrom: dotPosition to: self size
```
<figure><img src="image_87.png" /><figcaption>**Figure 7.22:** Changing the `suffix` method in the debugger: fixing the off-by-one error after an SUnit assertion failure.</figcaption></figure>

When we run this method, the execution of the `Halt` now will bring up the pre-debugger, from where we can either proceed, or go into the debugger (and from there look at variables, step through the computation, and edit the code).

That's all there is to the debugger, but it's not all there is to the `suffix` method. The initial bug should have made you realize that if there is no dot in the target string, the `suffix` method will raise an error. This isn't the behaviour that we want, so let's add a second test to specify what should happen in this case.

```测试
        testSuffixNotFoundError
        self assert: 'readme' suffix = ''
```

Lastly, add `testNoSuffix` to the test suite in class `StringTest`, and watch the test raise an error. Enter the debugger by selecting the erroneous test in SUnit, and edit the code so that the test passes. The easiest and clearest way to do this is to replace the `detect:` message by `detect:ifNone:`, where the second argument is a block that simply returns the string size.

We will learn more about SUnit in Chapter : SUnit.
<figure><img src="image_88.png" /><figcaption>Figure 7.23: The Process Browser showing all the active thread by priority.</figcaption></figure>

## 7.5 The process browser

Pharo is a multi-threaded system, and there are many lightweight processes (also known as threads) running concurrently in your image. In the future the Pharo virtual machine may take advantage of multiple processors when they are available, but at present, concurrency is implemented by time-slicing.

The Process Browser is a cousin of the debugger that lets you look at the various processes running inside Pharo. You can open it using the World Menu, by selecting Tools > Process Browser (figure 7.23 shows a screenshot). The top-left pane lists all of the processes in Pharo, in priority order, from the timer interrupt watcher at priority 80 to the idle process at priority 10. Of course, on a uniprocessor, the only process that can be running when you look is the UI process; all others will be waiting for some kind of event.

By default, the display of processes is static; it can be updated by right-clicking and selecting Turn on auto-update (a).

If you select a process in the top-left pane, its stack trace is displayed in the top-right pane, just as with the debugger. If you select a stack frame, the corresponding method is displayed in the bottom pane. The process browser is not equipped with mini-inspectors for self and thisContext, but right-clicking on the stack frames provide equivalent functionality.
## 7.6 Finding methods

The *Finder* is one of several code search tools in Pharo to help you find methods by name (or even functionality). We've discussed it in some length in Chapter: A Quick Tour of Pharo.

## 7.7 Chapter summary

In order to develop effectively with Pharo, it is important to invest some effort into learning the tools available in the environment.

* The standard *browser* is your main interface for browsing existing packages, classes, method protocols and methods, and for defining new ones.

* The browser offers several useful shortcuts to directly jump to senders or implementors of a message, versions of a method, and so on.

* From any of the tools, you can highlight the name of a class or a method and immediately jump to a browser by using the keyboard shortcut CMD-b.

* You can also browse the Pharo system programmatically by sending messages to `SystemNavigation default`.

* The *Inspector* is a tool that is useful for exploring and interacting with live objects in your image.

* You can even inspect tools by meta-clicking to bring up their morphic halo and selecting the debug handle.

* The *Debugger* is a tool that not only lets you inspect the run-time stack of your program when an error is raised, but it also enables you to interact with all of the objects of your application, including the source code. In many cases you can modify your source code from the debugger and continue executing. The debugger is especially effective as a tool to support test-first development in tandem with SUnit (Chapter: SUnit).

* The *Process Browser* lets you monitor, query and interact with the processes current running in your image.

* The *Finder* is a tool for locating methods.
# Sharing code and source control

The consequence of programming in a world of live objects rather than with files and a text editor is that you have to do something explicit to export your program from your Pharo image. The old way of doing this is by creating a *fileout* or a *change set*, which are essentially encoded text files that can be imported into another system. The preferred way of sharing code in Pharo is to save packages and share them using a versioned repository on a server. Up to Pharo 50, this is done using a tool called Monticello, and is a much more powerful and effective way to work, especially when working in a team. In the future Pharo will officially offer support for Git and hosting on servers such as GitHub, BitBucket and more.

We gave you a quick overview of Monticello, Pharo's packaging tool, in Chapter : A First Application. However, Monticello has many more features than were discussed there. Because Monticello manages *packages*, before telling you more about Monticello, it's important that we first explain exactly what a package is.

## 8.1 Packages: groups of classes and methods

We have pointed out earlier (in Chapter : A First Application) packages are more or less a group of classes and methods. Now we will see exactly what the relationship is. The package system is a simple, lightweight way of organizing Pharo source code that exploits a simple naming convention.

Let's explain this using an example. Suppose that you are developing a framework to facilitate the use of relational databases from Pharo. You have decided to call your framework PharoLink, and have created a couple of classes such as `OracleConnection`, `MySQLConnection`, `PostgresConnection` but also
DBTable, DBRow, DBQuery, and so on. These classes are placed inside a package called PharoLink. However, not all of your code will reside in these classes. For example, you may also have a series of methods to convert objects into an SQL-friendly format: `Object>>#asSQL`, `String>>#asSQL`, or `Date>>#asSQL`.

These methods belong in the same package as the classes. But clearly the whole of class Object does not belong in your package! So you need a way of putting certain methods in a package, even though the rest of the class is in another package.

The way that you do this is by placing those methods in a protocol (of Object, String, Date, and so on) named `*PharoLink` (note the initial asterisk). The `*PharoLink` protocols added to the package named PharoLink. To be precise, the rules for what goes in a package are as follows.

A package named `Foo` contains: 1. All *class definitions* of classes in the package `Foo`.

2. All *methods* in any *class* in protocols named `*Foo` or `*foo` (When performing this comparison, the case of the letters in the names is ignored.), or whose name starts with `*Foo-` or `*foo-`.

3. All *methods* in classes in the package `Foo` *except* for those methods in protocols whose names start with `*`: Because classes of package `Foo` can be also extended by other packages.

A consequence of these rules is that each class definition and each method belongs to exactly one package.

## Accessing packages

The class `RPackage` represents packages. The class `RPackageOrganizer` implements a singleton that holds all the Pharo packages. The following expressions are examples of the queries that you can perform.

`(RPackageOrganizer default packageNamed: 'AST-Core') definedClassNames`

`(RPackageOrganizer default packageNamed: 'AST-Core') extendedClasses`

## Basic Monticello

When you open the Monticello browser, you will see two list panes and a row of buttons, as shown in Figure 8.1. The left-hand pane lists all of the packages that have been loaded into the image that you are running; the particular version of the package is shown in parentheses after the name.

The right-hand pane lists all of the source code repositories that Monticello knows about, usually because it has loaded code from them. If you select a
<figure><img src="image_89.png" /><figcaption>Figure 8.1: The Monticello browser.</figcaption></figure>

package in the left pane, the right pane is filtered to show only those repositories that contain versions of the selected package.

## The package-cache

One of the repositories is a directory named *package-cache*, which is a subdirectory of the directory in which your image is running. When you load code from or write code to a remote repository, a copy is also saved in the package cache. This can be useful if the network is not available and you need to access a package. Also, if you are given a Monticello (.mcz) file directly, for example as an email attachment, the most convenient way to access it is to place it in the package-cache directory.

## Adding repositories

To add a new repository to the list, click the `+Repository`, and choose the kind of repository from the pop-up menu. Let's add an HTTP repository.

**To do** Open Monticello, click on `+Repository`, and select HTTP. Edit the dialog to read:

```
MCHttpRepository
  location: 'http://squeaksource.com/PharoByExample'
  user: ''
  password: ''
```

Click on Open to open a repository browser on this repository. You should see something like Figure 8.2. On the left is a list of all of the packages in the repository; if you select one, then the pane on the right will show all of the versions of the selected package in this repository.
<figure><img src="image_90.png" /><figcaption>**Figure 8.2:** A Repository browser.</figcaption></figure>

## Browsing versions

If you select one of the versions, you can Browse it (without loading it into your image), Load it, or look at the Changes that will be made to your image by loading the selected version. You can also make a Copy of a version of a package, which you can then write to another repository.

As you can see, the names of versions contain the name of the package, the name of the author of the version, and a version number. The version name is also the name of the file in the repository. Never change these names; correct operation of Monticello depends on them! Monticello version files are just zip archives, and if you are curious you can unpack them with a zip tool, but the best way to look at their contents is using Monticello itself.

## Creating a package

To create a package with Monticello, you have to do two things: write some code, and tell Monticello about it.

**To do** Create a package called PBE, and put a couple of classes in it, as shown in Figure 8.3. Also, create a method in an existing class, such as Object, and put it in the same package as your classes – see Figure 8.4.

## Committing a package

When you add a package via the class browser, Monticello automatically add the package to its list. PBE is now in list of packages; the package entry will be marked with an asterisk to show that the version in the image has not yet been written to any repository (It is said to be *dirty*).
<figure><img src="image_91.png" /><figcaption>Figure 8.3: Two classes and one extension in the PBE package.</figcaption></figure>

<figure><img src="image_92.png" /><figcaption>Figure 8.4: An extension method that is also be in the PBE package.</figcaption></figure>
<figure><img src="image_93.png" /><figcaption>**Figure 8.5:** The as-yet-unsaved PBE package in Monticello.</figcaption></figure>

Initially, the only repository associated with this package will be your package cache, as shown in Figure 8.5. That’s OK: you can still save the code, which will cause it to be written to the package cache. Just click Save and you will be invited to provide a log message for the version of the package that you are about to save, as shown in Figure 8.6; when you accept the message, Monticello will save your package. To indicate this, the asterisk decorating the name in Monticello’s package pane will be removed, and the version number added.

## Introducing a change

If you then make a change to the package – say by adding a method to one of the classes – the asterisk will re-appear, showing that you have unsaved changes. If you open a repository browser on the package cache, you can select the saved version, and use Changes and the other buttons. You can of course save the new version to the repository too; once you Refresh the repository view, it should look like Figure 8.7.

To save the new package to a repository other than the package cache, you need to first make sure that Monticello knows about the repository, adding it if necessary. Then you can use the Copy in the package-cache repository browser, and select the repository to which the package should be copied. You can also associate the desired repository with the package by right-clicking on the repository and selecting add to package... and select the corresponding package. Once the package knows about a repository, you can save a new version by selecting the repository and the package in the Monticello Browser, and clicking Save. Of course, you must have permission to write to a repository. The PharoByExample repository on SqueakSource is world readable but not world writable, so if you try and save there, you will see an error message.

However, you can create your own repository and save your code there. Nowadays the favorite code repositories are http://www.smalltalkhub.org and http://ss3.gemstone.com. This is especially useful as a mechanism to share
<figure><img src="image_94.png" /><figcaption>Figure 8.6: Providing a log message for a new version of a package.</figcaption></figure>

<figure><img src="image_95.png" /><figcaption>Figure 8.7: Two versions of our package are now in the package cache.</figcaption></figure>
<figure><img src="image_96.png" /><figcaption>**Figure 8.8:** The versions browser showing two versions of the ObjTest>>testIVOffset method.</figcaption></figure>

your code with others and to make sure that you can use automated build systems such as Jenkins or Travis.

If you do try and save to a repository where you don't have write permission, a version will nevertheless be written to the package-cache. So you can recover by editing the repository information (right-click in the Monticello Browser) or choosing a different repository, and then using Copy from the package-cache browser.

## 8.2 Source control

### Versions of a method

When you save a new version of a method, the old one is not lost. Pharo keeps all of the old versions (assuming that you are using the same image and that you saved it), and allows you to compare different versions and to go back (revert) to an old version.

The browse > versions (v) menu item gives access to the successive modifications made to the selected method. In Figure 8.8 we can see two versions of a method.
The top pane displays one line for each version of the method, listing the name of the programmer who wrote it, the date and time at which it was saved, the names of the class and the method, and the protocol in which it was defined. The current (active) version is at the top of the list.

The existence of the versions browser means that you never have to worry about preserving code that you think might no longer be needed. If you find that you *do* need it, you can always revert to the old version, or copy the needed code fragment out of the old version and paste it into a another method. Get into the habit of using versions; commenting out code that is no longer needed is a bad practice because it makes the current code harder to read. Pharoers rate code readability extremely highly.

**Hint:** What if you delete a method entirely, and then decide that you want it back? You can find the deletion in a change set, where you can ask to see versions by right-clicking. The change set browser is described in section 8.2.

## Change sets and the changesorter

Whenever you are working in Pharo, any changes that you make to methods and classes are recorded in a *change set*. This includes creating new classes, renaming classes, changing categories, adding methods to existing classes – just about everything of significance. However, arbitrary *Do its* are not included.

At any time, many change sets exist, but only one of them – *ChangeSet current* – is collecting the changes that are being made to the image. You can see which change set is current and can examine all of the change sets using the change sorter, available by selecting *World > Tools... > Change Sorter*.

Figure 8.9 shows the dual change sorter browser. The title bar shows which change set is current, and this change set is selected when the change sorter opens.

Other change sets can be selected in the top-left pane; the right-click menu allows you to make a different change set current, or to create a new change set. The next pane lists all of the classes affected by the selected change set (with their categories). Selecting one of the classes displays the names of its methods that are also in the change set (*not* all of the methods in the class) in the left central pane, and selecting a method name displays the method definition in the bottom pane.

The change sorter also lets you delete classes and methods from the change set using the right-click menu on the corresponding items.

The change sorter allows you to simultaneously view two change sets, one on the left hand side and the other on the right. This layout supports the change sorter's main feature, which is the ability to move or copy changes from one change set to another, as shown by the right-click menu in Figure 8.9. It is also possible to copy individual methods from one side to the other.
<figure><img src="image_97.png" /><figcaption>**Figure 8.9:** The Change Sorter showing all the changes of one changeset and offering actions to move changes to other changesets.</figcaption></figure>

You may be wondering why you should care about the composition of a
change set. The answer is that change sets provide a simple mechanism for
exporting code from Pharo to the file system, from where it can be imported
into another Pharo image. Change set export is known as Filing-out, and
can be accomplished using the right-click menu on any change set, class or
method in either browser. Repeated file outs create new versions of the file,
but change sets are not a versioning tool like Monticello: they do not keep
track of dependencies.

Before the advent of Monticello, change sets were the main means for ex-
changing code between Pharoers. They have the advantage of simplicity (the
file out is just a text file, although we don't recommend that you try to edit
them with a text editor), and a degree of portability.

The main drawback of change sets, compared to Monticello packages, is that
they do not support the notion of dependencies. In spite of these shortcom-
ings, change sets still have their uses. In particular, you may find change sets
on the Internet that you want to look at and perhaps use. So, having filed out
a change set using the change sorter, we will now tell you how to file one in.
This requires the use of another tool, the file list browser. Note that dropping
a changeset on Pharo itself works brings a pop up to ask you whether you
want to load or browse the code contained in a changeset.
<figure><img src="image_98.png" /><figcaption>Figure 8.10: A file list browser.</figcaption></figure>

## 8.3 The File List Browser

The file list browser is in fact a general-purpose tool for browsing the file system (as well as FTP servers) from Pharo. You can open it from the World > Tools... > File Browser menu. What you see of course depends on the contents of your local file system, but a typical view is shown in Figure 8.10.

When you first open a file list browser it will be focused on the current directory, that is, the one from which you started Pharo. The title bar shows the directory name. The larger pane on the left-hand side can be used to navigate the file system in the conventional way. When a directory is selected, the files that it contains (but not the directories) are displayed on the right. This list of files can be filtered by entering a Unix-style pattern in the small box at the top-left of the window. Initially, this pattern is `*`, which matches all file names, but you can type a different string there and accept it, changing the pattern. (Note that a `*` is implicitly prepended and appended to the pattern that you type.) The sort order of the files can be changed using the name, date and size buttons. The rest of the buttons depend on the name of the file selected in the browser. In Figure 8.10, the file name has the suffix `.st`, so the browser assumes that it is pharo code, and provides the possible actions as buttons.

Because the choice of buttons to display depends on the file's *name*, and not on its contents, sometimes the button that you want won't be on the screen.
<figure><img src="image_99.png" /><figcaption>**Figure 8.11:** A File Contents Browser opened on a package.</figcaption></figure>

However, the full set of options is always available from the right-click more... menu, so you can easily work around this problem.

The code button is perhaps the most useful for working with change sets; it opens a browser on the contents of the change set file or even an MC package; an example is shown in Figure 8.11. The file contents browser is similar to the browser except that the code is not loaded in memory.

## 8.4 In Pharo, you can't lose code

It is quite possible to crash Pharo: as an experimental system, Pharo lets you change anything, including things that are vital to make Pharo work!

The good news is that you will never lose any work, even if you crash and go back to the last saved version of your image, which might be hours old. This is because all of the code that you executed is saved in the `.changes` file. This excludes Playground snippets, those are stored inside `/pharo-local/play-chace` and they can be searched using Spotter (the results are displayed under Playground-cached pages section).

So here are the instructions on how to get your code back. There is no need to read this until you need it. However, when you do need it, you'll find it here waiting for you.

In the worst case, you can use a text editor on the `.changes` file, but since it is many megabytes in size, this can be slow and is not recommended. Pharo
offers you better ways.

## How to get your code back

Restart Pharo from the most recent snapshot, and select World > Tools... > Recover lost changes.

Smalltalk recover: 10000.

ChangeList browseRecentLog.

ChangeList browseRecent: 2000.

This will give you the opportunity to decide how far back in history you wish to browse. Normally, it's sufficient to browse changes as far back as the last snapshot. (You can get much the same effect by editing ChangeList browseRecent: 2000 so that the number 2000 becomes something else, using trial and error.)

Once you have a *recent changes* browser, showing, say, changes back as far as your last snapshot, you will have a list of everything that you have done to Pharo during that time. You can delete items from this list using the right-click menu. When you are satisfied, you can file-in what is left, thus incorporating the changes into your new image. It's a good idea to start a new change set, using the ordinary change set browser, before you do the file in, so that all of your recovered code will be in a new change set. You can then file out this change set.

One useful thing to do in the *recent changes* browser is to remove *doIts*. Usually, you won't want to file in (and thus re-execute) *doIts*. However, there is an exception. Creating a class shows up as a *doIt*.

*Before you can file in the methods for a class, the class must exist.* So, if you have created any new classes, *first file-in* the class creation *doIts*, then *remove doIts* and file in the methods.

When I am finished with the recovery, I like to file out my new change set, quit Pharo without saving the image, restart, and make sure that the new change set files back in cleanly.

## 8.5 Chapter summary

* *Monticello* is a tool for exporting, importing, versioning and sharing packages of classes and methods.

* A *Monticello* package consists of classes, and related methods in other packages.

* *Change sets* are automatically generated logs of all changes to the source code of your image. They have largely been superseded by *Monticello* as a means to store and exchange versions of your source code, but are
still useful, especially for recovering from catastrophic failures, however
rare these may be.

* The *file list browser* is a tool for browsing the file system. It also allows you to *File* in source code from the file system.

* In case your image crashes before you could save it or backup your source code with Monticello, you can always recover your most recent changes using a *change list browser*. You can then select the changes you want to replay and file them into the most recent copy of your image.
CHAPTER 9

SUnit

SUnit is a minimal yet powerful framework that supports the creation and
deployment of tests. As might be guessed from its name, the design of SUnit
focussed on Unit Tests, but in fact it can be used for integration tests and
functional tests as well. SUnit was originally developed by Kent Beck and
subsequently extended by Joseph Pelrine and others to incorporate the notion
of a resource (discussed below).

In this chapter we start by discussing why we test, and what makes a good
test. We then present a series of small examples showing how to use SUnit.
Finally, we look at the implementation of SUnit, so that you can understand
how Pharo uses the power of reflection in supporting its tools. Note that the
version documented in this chapter and used in Pharo is a modified version of
SUnit3.3.

9.1 Introduction

The interest in testing and Test Driven Development is not limited to Pharo.
Automated testing has become a hallmark of the *Agile software development*
movement, and any software developer concerned with improving software
quality would do well to adopt it. Indeed, developers in many languages have
come to appreciate the power of unit testing, and versions of *xUnit* now exist
for every programming language.

Neither testing, nor the building of test suites, is new. By now, everybody
knows that tests are a good way to catch errors. eXtreme Programming, by
making testing a core practice and by emphasizing *automated* tests, has helped
to make testing productive and fun, rather than a chore that programmers
dislike. The Smalltalk community has a long tradition of testing because of the
incremental style of development supported by its programming environment. In traditional Smalltalk development, the programmer would write tests in a playground as soon as a method was finished. Sometimes a test would be incorporated as a comment at the head of the method that it exercised, or tests that needed some set up would be included as example methods in the class. The problem with these practices is that tests in a playground are not available to other programmers who modify the code. Comments and example methods are better in this respect, but there is still no easy way to keep track of them and to run them automatically. Tests that are not run do not help you to find bugs! Moreover, an example method does not inform the reader of the expected result: you can run the example and see the (perhaps surprising) result, but you will not know if the observed behaviour is correct.

SUnit is valuable because it allows us to write tests that are self-checking: the test itself defines what the correct result should be. It also helps us to organize tests into groups, to describe the context in which the tests must run, and to run a group of tests automatically. In less than two minutes you can write tests using SUnit, so instead of writing small code snippets in a playground, we encourage you to use SUnit and get all the advantages of stored and automatically executable tests.

## 9.2 Why testing is important

Unfortunately, many developers believe that tests are a waste of their time. After all, they do not write bugs, only other programmers do that. Most of us have said, at some time or other: I would write tests if I had more time. If you never write a bug, and if your code will never be changed in the future, then indeed tests are a waste of your time. However, this most likely also means that your application is trivial, or that it is not used by you or anyone else. Think of tests as an investment for the future: having a suite of tests is quite useful now, but it will be extremely useful when your application, or the environment in which it runs, changes in the future.

Tests play several roles. First, they provide documentation of the functionality that they cover. This documentation is active: watching the tests pass tells you that the documentation is up to date. Second, tests help developers to confirm that some changes that they have just made to a package have not broken anything else in the system, and to find the parts that break when that confidence turns out to be misplaced. Finally, writing tests during, or even before, programming forces you to think about the functionality that you want to design, and how it should appear to the client code, rather than about how to implement it.

By writing the tests first, i.e., before the code, you are compelled to state the context in which your functionality will run, the way it will interact with the client code, and the expected results. Your code will improve. Try it.
We cannot test all aspects of any realistic application. Covering a complete
application is simply impossible and should not be the goal of testing. Even
with a good test suite some bugs will still creep into the application, where
they can lay dormant waiting for an opportunity to damage your system. If
you find that this has happened, take advantage of it! As soon as you uncover
the bug, write a test that exposes it, run the test, and watch it fail. Now you
can start to fix the bug: the test will tell you when you are done.

9.3 What makes a good test?

Writing good tests is a skill that can be learned by practicing. Let us look at
the properties that tests should have to get the maximum benefit.

*Tests should be repeatable.* You should be able to run a test as often as you want, and always get the same answer.

*Tests should run without human intervention.* You should be able to run them unattended.

*Tests should tell a story.* Each test should cover one aspect of a piece of code. A test should act as a scenario that you or someone else can read to understand a piece of functionality.

*Tests should have a change frequency lower than that of the functionality they cover.*
You do not want to have to change all your tests every time you modify your
application. One way to achieve this is to write tests based on the public
interfaces of the class that you are testing. It is OK to write a test for a private
*helper method* if you feel that the method is complicated enough to need the
test, but you should be aware that such a test may have to be changed, or
thrown away entirely, when you think of a better implementation.

One consequence of such properties is that the number of tests should be somewhat proportional to the number of functions to be tested: changing one aspect of the system should not break all the tests but only a limited number. This is important because having 100 tests fail should send a much stronger message than having 10 tests fail. However, it is not always possible to achieve this ideal: in particular, if a change breaks the initialization of an object, or the set-up of a test, it is likely to cause all of the tests to fail.

Several software development methodologies such as eXtreme Programming and Test-Driven Development (TDD) advocate writing tests before writing code. This may seem to go against our deep instincts as software developers. All we can say is: go ahead and try it. We have found that writing the tests before the code helps us to know what we want to code, helps us know when we are done, and helps us conceptualize the functionality of a class and to design its interface. Moreover, test-first development gives us the courage to go fast, because we are not afraid that we will forget something important.
Writing tests is not difficult in itself. Choosing *what* to test is much more difficult. The pragmatic programmers offer the "right-BICEP" principle. It stands for:

* Right: Are the results right?

* B: Are all the boundary conditions correct?

* I: Can you check inverse relationships?

* C: Can you cross-check results using other means?

* E: Can you force error conditions to happen?

* P: Are performance characteristics within bounds?

Now let's write our first test, and show you the benefits of using SUnit.

## 9.4 SUnit by example

Before going into the details of SUnit, we will show a step by step example. We use an example that tests the class `Set`. Try entering the code as we go along.

### Step 1: Create the test class

First you should create a new subclass of `Case` called `MyExampleSetTest`. Add two instance variables so that your new class looks like this:

```java
TestCase subclass: #MyExampleSetTest
instanceVariableNames: 'full empty'
classVariableNames: ''
package: 'MySetTest'
```

We will use the class `MyExampleSetTest` to group all the tests related to the class `Set`. It defines the context in which the tests will run. Here the context is described by the two instance variables `full` and `empty` that we will use to represent a full and an empty set.

The name of the class is not critical, but by convention it should end in `Test`. If you define a class called `Pattern` and call the corresponding test class `PatternTest`, the two classes will be alphabetized together in the browser (assuming that they are in the same package). It is critical that your class is a subclass of `Case`.

### Step 2: Initialize the test context

The message `Case >> setup` defines the context in which the tests will run, a bit like an initialize method. `setup` is invoked before the execution of each test method defined in the test class.
Define the `setup` method as follows, to initialize the empty variable to refer to an empty set and the `full` variable to refer to a set containing two elements.

```groovy
MyExampleSetTest >>setup
empty := Set new.
full := Set with: 5 with: 6
```

In testing jargon the context is called the * fixture * for the test.

### Step 3: write some test methods

Let's create some tests by defining some methods in the class `MyExampleSetTest`. Each method represents one test. The names of the methods should start with the string `'test'` so that SUnit will collect them into test suites. Test methods take no arguments.

Define the following test methods. The first test, named `testIncludes`, tests the `includes:` method of `Set`. The test says that sending the message `includes:` 5 to a set containing 5 should return true. Clearly, this test relies on the fact that the `setup` method has already run.

```groovy
MyExampleSetTest >> testIncludes
self assert: (full includes: 5).
self assert: (full includes: 6)
```

The second test, named `testOccurrences`, verifies that the number of occurrences of 5 in `full` set is equal to one, even if we add another element 5 to the set.

```groovy
MyExampleSetTest >> testOccurrences
self assert: (empty occurrencesOf: 0) = 0.
self assert: (full occurrencesOf: 5) = 1.
full add: 5.
self assert: (full occurrencesOf: 5) = 1
```

Finally, we test that the set no longer contains the element 5 after we have removed it.

```groovy
MyExampleSetTest >> testRemove
full remove: 5.
self assert: (full includes: 6).
self deny: (full includes: 5)
```

Note the use of the method `TestCase >> deny:` to assert something that should not be true. `aTest deny: anExpression` is equivalent to `aTest assert: anExpression not`, but is much more readable.

### Step 4: Run the tests

The easiest way to run the tests is directly from the browser. Simply click on the icon of the class name, or on an individual test method, and select `Run tests`
<figure><img src="image_100.png" /><figcaption>Figure 9.1: Running SUnit tests from the System Browser.</figcaption></figure>

(t) or press the icon. The test methods will be flagged green or red, depending on whether they pass or not (as shown in 9.1).

You can also select sets of test suites to run, and obtain a more detailed log of the results using the SUnit Test Runner, which you can open by selecting World > Test Runner.

The Test Runner, shown in Figure 9.2, is designed to make it easy to execute groups of tests.

The left-most pane lists all of the packages that contain test classes (i.e., subclasses of TestCase). When some of these packages are selected, the test classes that they contain appear in the pane to the right. Abstract classes are italicized, and the test class hierarchy is shown by indentation, so subclasses of ClassTestCase are indented more than subclasses of TestCase. ClassTestCase is a class offering utilities methods to compute test coverage.

Open a Test Runner, select the package MySetTest, and click the Run Selected button.

You can also run a single test (and print the usual pass/fail result summary) by executing a Print it on the following code: MyExampleSetTest run: #testRemove.

Some people include an executable comment in their test methods that allows running a test method with a Do it from the browser, as shown below.

MyExampleSetTest >> testRemove
"self run: #testRemove"
full remove: 5.
self assert: (full includes: 6).
self deny: (full includes: 5)
<figure><img src="image_101.png" /><figcaption>Figure 9.2: Running SUnit tests using the TestRunner.</figcaption></figure>

Introduce a bug in `MyExampleSetTest >> testRemove` and run the tests again. For example, change 6 to 7, as in:

```groovy
MyExampleSetTest >> testRemove
    full remove: 5.
    self assert: (full includes: 7).
    self deny: (full includes: 5)
```

The tests that did not pass (if any) are listed in the right-hand panes of the Test Runner. If you want to debug one, to see why it failed, just click on the name. Alternatively, you can execute one of the following expressions:

```groovy
(MyExampleSetTest selector: #testRemove) debug
MyExampleSetTest debug: #testRemove
```

## Step 5: Interpret the results

The method `assert:` is defined in the class `TestAsserter`. This is a superclass of `Cases` and therefore all other `Cases` subclasses and is responsible for all kind of test result assertions. The `assert:` method expects a boolean argument, usually the value of a tested expression. When the argument is true, the test passes; when the argument is false, the test fails.

There are actually three possible outcomes of a test: *passing*, *failing*, and *raising an error*.

* **Passing.** The outcome that we hope for is that all of the assertions in the test are true, in which case the test passes. In the test runner, when all of the tests pass, the bar at the top turns green. However, there are two other ways that running a test can go wrong.
* **Failing.** The obvious way is that one of the assertions can be false, causing the test to fail.

* **Error.** The other possibility is that some kind of error occurs during the execution of the test, such as a *message not understood* error or an *index out of bounds* error. If an error occurs, the assertions in the test method may not have been executed at all, so we can't say that the test has failed; nevertheless, something is clearly wrong!

In the *test runner*, failing tests cause the bar at the top to turn yellow, and are listed in the middle pane on the right, whereas tests with errors cause the bar to turn red, and are listed in the bottom pane on the right.

Modify your tests to provoke both errors and failures.

## 9.5 The SUnit cookbook

This section will give you more details on how to use SUnit. If you have used another testing framework such as JUnit, much of this will be familiar, since all these frameworks have their roots in SUnit. Normally you will use SUnit's GUI to run tests, but there are situations where you may not want to use it.

### Other assertions

In addition to `assert:` and `deny:`, there are several other methods that can be used to make assertions.

First, `TestAsserter >> assert: description: ` and `TestAsserter >> deny: description: ` take a second argument which is a message string that describes the reason for the failure, if it is not obvious from the test itself. These methods are described in Section 9.7.

Next, `SUnit` provides two additional methods, `TestAsserter >> should: raise:` and `TestAsserter >> shouldn't: raise:` for testing exception propagation.

For example, you would use `self should: aBlock raise: anException` to test that a particular exception is raised during the execution of `aBlock`. The method below illustrates the use of `should: raise: `.

```python
MyExampleSetTest >> testIllegal
    self should: [ empty at: 5 ] raise: Error.
    self should: [ empty at: 5 put: #zork ] raise: Error
```

Try running this test. Note that the first argument of the `should:` and `shouldnt:` methods is a block that contains the expression to be executed.

### Running a single test

Normally, you will run your tests using the Test Runner or using your code browser. If you don't want to launch the Test Runner from the World menu,
<figure><img src="image_102.png" /><figcaption>**Figure 9.3:** The four classes representing the core of SUnit.</figcaption></figure>

you can execute `TestRunner open`. You can also run a single test as follows:

```
MyExampleSetTest run: #testRemove
>>> 1 run, 1 passed, 0 failed, 0 errors
```

## Running all the tests in a test class

Any subclass of `Case` responds to the message `suite`, which will build a test suite that contains all the methods in the class whose names start with the string `test`.

To run the tests in the suite, send it the message `run`. For example:

```
MyExampleSetTest suite run
>>> 5 run, 5 passed, 0 failed, 0 errors
```

## Must I subclass `Case`?

In JUnit you can build a `TestSuite` from an arbitrary class containing `test*` methods. In SUnit you can do the same but you will then have to create a suite by hand and your class will have to implement all the essential `Case` methods like `assert`. We recommend, however, that you not try to do this. The framework is there: use it.

## 9.6 The SUnit framework

SUnit consists of four main classes: `Case`, `TestSuite`, `TestResult`, and `TestResource`, as shown in Figure 9.3. The notion of a *test resource* represents a resource that is expensive to set-up but which can be used by a whole series of tests. A `TestResource` specifies a `setup` method that is executed just once before a suite of tests; this is in distinction to the `Case` `>>` `setup` method, which is executed before each test.
## TestCase

Case is an abstract class that is designed to be subclassed. Each of its subclasses represents a group of tests that share a common context (that is, a test suite). Each test is run by creating a new instance of a subclass of TestCase, runningatti, running the test method itself, and then sending the `tearDown`.

The context is specified by instance variables of the subclass and by the specialization of the method `setup`, which initializes those instance variables. Subclasses of TestCase can also override method `tearDown`, which is invoked after the execution of each test, and can be used to release any objects allocated during `setup`.

## TestSuite

Instances of the class TestSuite contain a collection of test cases. An instance of TestSuite contains tests, and other test suites. That is, a test suite contains sub-instances of TestCase and TestSuite.

Both individual test cases and test suites understand the same protocol, so they can be treated in the same way (for example, both can be `run`). This is in fact an application of the Composite pattern in which TestSuite is the composite and the test cases are the leaves.

## TestResult

The class TestResult represents the results of a TestSuite execution. It records the number of tests passed, the number of tests failed, and the number of errors signalled.

## TestResource

One of the important features of a suite of tests is that they should be independent of each other. The failure of one test should not cause an avalanche of failures of other tests that depend upon it, nor should the order in which the tests are run matter. Performing `setup` before each test and `tearDown` afterwards helps to reinforce this independence.

However, there are occasions where setting up the necessary context is just too time-consuming for it to be done before the execution of each test. Moreover, if it is known that the test cases do not disrupt the resources used by the tests, then it is wasteful to set them up afresh for each test. It is sufficient to set them up once for each suite of tests. Suppose, for example, that a suite of tests needs to query a database, or do analysis on some compiled code. In such cases, it may make sense to set up the database and open a connection to it, or to compile some source code, before any of the tests start to run.
Where should we cache these resources, so that they can be shared by a suite of tests? The instance variables of a particular `Case` subclass won't do, because a `TestCase` instance persists only for the duration of a single test (as mentioned before, the instance is created anew for each test method). A global variable would work, but using too many global variables pollutes the name space, and the binding between the global and the tests that depend on it will not be explicit. A better solution is to put the necessary resources in a singleton object of some class. The class `TestResource` exists to be subclassed by such resource classes. Each subclass of `TestResource` understands the message current, which will answer a singleton instance of that subclass. Methods `up` and `down` should be overridden in the subclass to ensure that the resource is initialized and finalized.

One thing remains: somehow, `Suite` has to be told which resources are associated with which test suite. A resource is associated with a particular subclass of `Case` by overriding the `class` method resources.

By default, the resources of a `Suite` are the union of the resources of the `Cases` that it contains.

Here is an example. We define a subclass of `TestResource` called `MyTestResource`. Then we associate it with `MyCase` by overriding the class method `MyCase class >> resources` to return an array of the test resource classes that `MyCase` will use.

```java
TestResource subclass: #MyTestResource
instanceVariableNames: ''

MyCase class >> resources
  "Associate the resource with this class of test cases"

  ^ { MyTestResource }
```

## Exercise

The following trace (written to the `Transcript`) illustrates that a global set up is run before and after each test in a sequence. Let's see if you can obtain this trace yourself.

```
MyTestResource >>atti has run.
MyTestCase >>atti has run.
MyTestCase >> attiOne has run.
MyTestCase >> attiDown has run.
MyTestCase >>atti has run.
MyTestCase >> attiTwo has run.
MyTestCase >>attiDown has run.
MyTestResource >>attiDown has run.
```
Create new classes MyTestResource and MyTestCase which are subclasses of TestResource and TestCase respectively. Add the appropriate methods so that the following messages are written to the Transcript when you run your tests.

**Solution.** You will need to write the following six methods.

```java
MyCase >> setUp
Transcript show: 'MyCase>>setup has run.'; cr

MyCase >> tearDown
Transcript show: 'MyCase>>tearDown has run.'; cr

MyCase >> testOne
Transcript show: 'MyCase>>testOne has run.'; cr

MyCase >> testTwo
Transcript show: 'MyCase>>testTwo has run.'; cr

MyCase class >> resources
^ Array with: MyTestResource

MyTestResource >> setUp
Transcript show: 'MyTestResource>>setup has run'; cr

MyTestResource >> tearDown
Transcript show: 'MyTestResource>>tearDown has run.'; cr
```

## 9.7 Advanced features of SUnit

In addition to TestResource, SUnit contains assertion description strings, logging support, the ability to skip tests, and resumable test failures.

### Assertion description strings

The TestAsserter assertion protocol includes a number of methods that allow the programmer to supply a description of the assertion. The description is a String; if the test case fails, this string will be displayed by the test runner. Of course, this string can be constructed dynamically.

```text
...
e := 42.
self assert: e = 23 description: 'expected 23, got ', e printString
...
```

The relevant methods in TestAsserter are:

```
assert: description:
deny: description:
```
```
should description:
```

```
shouldnt description:
```

## Using `assert:equals`:

In addition to `assert:`, there is also `assert:equals:` that offers a better report in case of error (incidentally, `assert:equals:` uses `assert:description:`).

For example, the two following tests are equivalent. However, the second one will report the value that the test is expecting: this makes easier to understand the failure. In this example, we suppose that `aDateAndTime` is an instance variable of the test class.

```python
testAsDate
    self assert: aDateAndTime asDate = ('February 29, 2004' asDate
                                        translateTo: 2 hours).
```

```python
testAsDate
    self
        assert: aDateAndTime asDate
        equals: ('February 29, 2004' asDate translateTo: 2 hours).
```

## Logging support

The description strings mentioned above may also be logged to a `Stream`, such as the `Transcript` or a file stream. You can choose whether to log by overriding `isLogging` in your test class; you must also choose where to log by overriding `failureLog` to answer an appropriate stream. By default, the `Transcript` is used to log.

## Skipping tests

Sometimes in the middle of a development, you may want to skip a test instead of removing it or renaming it to prevent it from running. You can simply invoke the `TestAsserter` message `skip` on your test case instance. For example, the following test uses it to define a conditional test.

```python
OCCompiledMethodIntegrityTest >> testPragmas
```

```python
| newCompiledMethod originalCompiledMethod |
(Smalltalk globals hasClassNamed: #Compiler) ifFalse: [ ^ self skip
].
...
```
## 9.8 Continuing after a failure

SUnit also allows us to specify whether or not a test should continue after a failure. This is a really powerful feature that uses Pharo's exception mechanisms. To see what this can be used for, let's look at an example. Consider the following test expression:

```sruby
[aCollection do: [ :each | self assert: each even ]
```

In this case, as soon as the test finds the first element of the collection that isn't even, the test stops. However, we would usually like to continue, and see both how many elements, and which elements, aren't even (and maybe also log this information). You can do this as follows:

```sruby
[aCollection do: [ :each |
    self
        assert: each even
        description: each printString, ' is not even'
        resumable: true ]
```

This will print out a message on your logging stream for each element that fails. It doesn't accumulate failures, i.e, if the assertion fails 10 times in your test method, you'll still only see one failure. All the other assertion methods that we have seen are not resumable by default; `assert: p description: s` is equivalent to `assert: p description: s resumable: false`.

## 9.9 SUnit implementation

The implementation of SUnit makes an interesting case study of a Pharo framework. Let's look at some key aspects of the implementation by following the execution of a test.

### Running one test

To execute one test, we execute the expression `(aTestClass selector: aSymbol) run`.

The method `TestCase >> run` creates an instance of `TestResult` that will accumulate the results of the test, then it sends itself the message `TestCase >> run: (See Figure 9.4).

```sruby
TestCase >> run
    | result |
    result := self classForTestResult new.
    [ self run: result ]
        ensure: [ self classForTestResource resetResources: self resources
                    ].
        ^ result
```
<figure><img src="image_103.png" /><figcaption>Figure 9.4: Running one test.</figcaption></figure>

The method `TestCase >> run:` sends the message `runCase:` to the test result:

```
[ TestCase >> run: aResult
  aResult runCase: self ]
```

The method `TestResult >> runCase:` sends the message `TestCase >> run-Case` to an individual test, to execute the test. `TestResult >> runCase` deals with any exceptions that may be raised during the execution of a test, runs a `TestCase` by sending it the `runCase`, and counts the errors, failures, and passes.

```
[ TestResult >> runCase: aTestCase
  [ aTestCase announce: TestCaseStarted withResult: self.
    aTestCase runCase.
    aTestCase announce: TestCaseEnded withResult: self.
    self addPass: aTestCase ]
  on: self class failure, self class skip, self class warning, self class error
  do: [ :ex | ex sunitAnnounce: aTestCase toResult: self ]
]
```

The method `TestCase >> runCase` sends the messages `TestCase >>upa` and `TestCase >> teardown` as shown below.

```
[ TestCase >> runCase
  self resources do: [ :each | each availableFor: self ].
  [ self setUp.
    self performTest ] ensure: [
      self teardown.
      self cleanUpInstanceVariables ]
]
```
## Running a TestSuite

To run more than one test, we send the message run to a TestSuite that contains the relevant tests. TestCase class provides some functionality to build a test suite from its methods. The expression MyTestCase buildSuiteFrom- Selectors returns a suite containing all the tests defined in the MyTestCase class. The core of this process is:

```
TestCase class >> testSelectorS
    ^ (self selectors select: [ :each | (each beginsWith: 'test') and: [ each numArgs isZero ]])
```

The method TestSuite >> run creates an instance of TestResult, verifies that all the resources are available, and then sends itself the message TestSuite >> run: , which runs all the tests in the suite. All the resources are then released.

```
TestSuite >> run: aResult
    selfupa.
    [ self tests
        do: [ :each |
              each run: aResult.
              self announceTest: each.
              self changed: each ] ]
        ensure: [ self.tearDown ]

TestSuite >>upa
    self resources do: [ :each |
                         each isAvailable ifFalse: [ each signalInitializationError ]
                         ].

TestSuite >> tearDown
    self resourceClass resetResources: self resources
```

The class TestResource and its subclasses keep track of their currently created singleton instances that can be accessed and created using the class method TestResource class >> current. This instance is cleared when the tests have finished running and the resources are reset.

The resource availability check makes it possible for the resource to be re-created if needed, as shown in the class method TestResource class >> isAvailable. During the TestResource instance creation, it is initialized and the messageatti is sent to a test resource.

```
TestResource class >> isAvailable
    "This is (and must be) a lazy method. If my current has a value, an
    attempt to make me available has already been made: trust its
    result. If not, try to make me available."

    current ifNil: [ self makeAvailable ].
    ^ self isAlreadyAvailable
```
9.10 A piece of advices on testing

```kotlin
TestResource class >> current
    "This is a lazy accessor: the assert of self isAvailable does no
    work unless current isNil. However this method should normally
    be sent only to a resource that should already have been made
    available, e.g. in a test whose test case class has the resource
    class in its #resources, so should never be able to fail the
    assert.

    If the intent is indeed to access a possibly-unprepared or
    reset-in-earlier-test resource lazily, then preface the call of
    'MyResource current' with 'MyResource availableFor: self'."

self
    assert: self isAvailable
    description:
        'Sent #current to unavailable resource ', self name,
        '. Add it to test case'' class-side #resources (recommended)
        or send #availableFor: beforehand'.
^ current
```

## 9.10 A piece of advices on testing

While the mechanics of testing are easy, writing good tests is not. Here is some advice on how to design tests.

### Self-contained tests

You do not want to have to change your tests each time you change your code, so try to write the tests so that they are self-contained. This can be difficult, but pays off in the long term. Writing tests against stable interfaces supports this effort.

### Do not over-test

Try to build your tests so that they do not overlap. It is annoying to have many tests covering the same functionality, because one bug in the code will then break many tests at the same time. This is covered by Black's rule, below.

### Feathers' Rules for Unit tests

Michael Feathers, an agile process consultant and author, writes:

> A test is not a unit test if: it talks to the database, it communicates across the network, it touches the file system, it can't run at the same time as any of your other unit tests, or you have to do special things to your environment (such as editing config files) to run it. Tests that do these things aren't bad. Often they are worth writing, and they can be written in a unit test harness. However, it is important to be able to separate them from true unit tests so that we can keep a set of tests that we can run
*fast whenever we make our changes. Never get yourself into a situation where you don't want to run your unit test suite because it takes too long.*

## Unit Tests vs. Acceptance Tests

Unit tests capture one piece of functionality, and as such make it easier to identify bugs in that functionality. As far as possible try to have unit tests for each method that could possibly fail, and group them per class. However, for certain deeply recursive or complex setup situations, it is easier to write tests that represent a scenario in the larger application. These are called acceptance tests (or integration tests, or functional tests). Tests that break Feathers' rules may make good acceptance tests. Group acceptance tests according to the functionality that they test. For example, if you are writing a compiler, you might write acceptance tests that make assertions about the code generated for each possible source language statement. Such tests might exercise many classes, and might take a long time to run because they touch the file system. You can write them using SUnit, but you won't want to run them each time you make a small change, so they should be separated from the true unit tests.

## Black's Rule of Testing

For every test in the system, you should be able to identify some property for which the test increases your confidence. It's obvious that there should be no important property that you are not testing. This rule states the less obvious fact that there should be no test that does not add value to the system by increasing your confidence that a useful property holds. For example, several tests of the same property do no good. In fact, they do harm in two ways. First, they make it harder to infer the behaviour of the class by reading the tests. Second, because one bug in the code might then break many tests, they make it harder to estimate how many bugs remain in the code. So, have a property in mind when you write a test.

## 9.11 Chapter summary

This chapter explained why tests are an important investment in the future of your code. We explained in a step-by-step fashion how to define a few tests for the class Set. Then we gave an overview of the core of the SUnit framework by presenting the classes TestCase, TestResult, TestSuite and TestResources. Finally we looked deep inside SUnit by following the execution of a test and a test suite.

* To maximize their potential, unit tests should be fast, repeatable, in-dependent of any direct human interaction and cover a single unit of functionality.
* Tests for a class called `MyClass` belong in a class named `MyClassTest`, which should be introduced as a subclass of `Case`.

* Initialize your test data in a `setup` method.

* Each test method should start with the word `test`.

* Use the `Case` methods `assert`, `deny` and others to make assertions.

* Run tests!
<figure><img src="image_104.png" /></figure>
CHAPTER 10

Basic classes

Pharo is a really simple language but powerful language. Part of its power
is not in the language but in its class libraries. To program effectively in
it, you will need to learn how the class libraries support the language and
environment. The class libraries are entirely written in Pharo, and can easily
be extended. (Recall that a package may add new functionality to a class even
if it does not define this class.)

Our goal here is not to present in tedious detail the whole of the Pharo class
library, but rather to point out the key classes and methods that you will need
to use (or subclass/override) to program effectively. In this chapter, we will
cover the basic classes that you will need for nearly every application: Object,
Number and its subclasses, Character, String, Symbol, and Boolean.

10.1 Object

For all intents and purposes, *Object* is the root of the inheritance hierarchy.
Actually, in Pharo the true root of the hierarchy is *ProtoObject*, which is used
to define minimal entities that masquerade as objects, but we can ignore this
point for the time being.

Object defines almost 400 methods (in other words, every class that you
define will automatically provide all those methods). Note: You can count the
number of methods in a class like so:

```
Object selectors size "Count the instance methods in Object"
Object class selectors size "Count the class methods"
```

Class *Object* provides default behaviour common to all normal objects, such as access, copying, comparison, error handling, message sending, and reflec-
tion. Also utility messages that all objects should respond to are defined here. Object has no instance variables, nor should any be added. This is due to several classes of objects that inherit from Object that have special implementations (SmallInteger and UndefinedObject for example) that the VM knows about and depends on the structure and layout of certain standard classes.

If we begin to browse the method protocols on the instance side of Object we will start to see some of the key behaviour it provides.

## Printing

Every object can return a printed form of itself. You can select any expression in a textpane and select the Print it menu item: this executes the expression and asks the returned object to print itself. In fact this sends the message printString to the returned object. The method printString, which is a template method, at its core sends the message printOn: to its receiver. The message printOn: is a hook that can be specialized.

Method Object>>printOn: is very likely one of the methods that you will most frequently override. This method takes as its argument a Stream on which a String representation of the object will be written. The default implementation simply writes the class name preceded by a dot. Object>>printString returns the String that is written.

For example, the class OpalCompiler does not redefine the method printOn: and sending the message printString to an instance executes the methods defined in Object.

```ruby
OpalCompiler new printString
>>> 'an OpalCompiler'
```

The class Color shows an example of printOn: specialization. It prints the name of the class followed by the name of the class method used to generate that color.

```ruby
Color >> printOn: aStream
| name |
(name := self name).
name = #unnamed
ifFalse: [
    ^ aStream
        nextPutAll: 'Color ';
        nextPutAll: name ].
self storeOn: aStream]]]
[[[
Color red printString
>>> 'Color red'
```

Note that the message printOn: is not the same as storeOn:. The message storeOn: writes to its argument stream an expression that can be used to
recreate the receiver. This expression is executed when the stream is read using the message readFrom:. On the other hand, the message printOn: just returns a textual version of the receiver. Of course, it may happen that this textual representation may represent the receiver as a self-evaluating expression.

**A word about representation and self-evaluating representation.** In functional programming, expressions return values when executed. In Pharo, messages (expressions) return objects (values). Some objects have the nice property that their value is themselves. For example, the value of the object true is itself i.e., the object true. We call such objects *self-evaluating objects*. You can see a *printed* version of an object value when you print the object in a playground. Here are some examples of such self-evaluating expressions.

```
true
>>> true
3@4
>>> (3@4)
$a
>>> $a
#(1 2 3)
>>> #(1 2 3)
Color red
>>> Color red
```

Note that some objects such as arrays are self-evaluating or not depending on the objects they contain. For example, an array of booleans is self-evaluating, whereas an array of persons is not. The following example shows that a dynamic array is self-evaluating only if its elements are:

```
{10@10. 100@100}
>>> {(10@10). (100@100)}
{Nautilus new . 100@100}
>>> an Array(a Nautilus (100@100))
```

Remember that literal arrays can only contain literals. Hence the following array does not contain two points but rather six literal elements.

```
#(10@10 100@100)
>>> #(10 #@ 10 100 #@ 100)
```

Lots of printOn: method specializations implement self-evaluating behavior. The implementations of Point>>printOn: and Interval>>printOn: are self-evaluating.

```
Point >> printOn: aStream
    "The receiver prints on aStream in terms of infix notation."
    aStream nextPut: $(. 
    x printOn: aStream.
```
```kotlin
aStream nextPut: $@.
(y notNil and: [y negative])
ifTrue: [
    "Avoid ambiguous @- construct"
    aStream space ].
y printOn: aStream.
aStream nextPut: $).

Interval >> printOn: aStream
aStream nextPut: $();
    print: start;
    nextPutAll: ' to: ';
    print: stop.
step =~ 1 ifTrue: [aStream nextPutAll: ' by: ';
    aStream nextPut: $)

1 to: 10
>>> (1 to: 10) "intervals are self-evaluating"
```

## Identity and equality

In Pharo, the message `= tests object equality` (i.e., whether two objects represent the same value) whereas `==` tests object *identity* (whether two expressions represent the same object).

The default implementation of object equality is to test for object identity:

```kotlin
Object >> = anObject
    "Answer whether the receiver and the argument represent the same
     object.
    If = is redefined in any subclass, consider also redefining the
     message hash."
    ^ self == anObject
```

This is a method that you will frequently want to override. Consider the case of Complex numbers as defined in the SciSmalltalk/PolyMath packages (PolyMath is a set of packages that offer support for numerical methods):

```kotlin
(1 + 2 i) = (1 + 2 i)
>>> true "same value"
(1 + 2 i) == (1 + 2 i)
>>> false "but different objects"
```

This works because Complex overrides `==` as follows:

```kotlin
Complex >> = anObject
    ^ anObject isComplex
        ifTrue: [ (real = anObject real) & (imaginary = anObject
                                                imaginary)]
        ifFalse: [ anObject adaptToComplex: self andSend: #=]
```
The default implementation of `Object>>~= (a test for inequality)` simply negates `Object>>=`, and should not normally need to be changed.

```python
(1 + 2 i) =~ (1 + 4 i)
>>> true
```

If you override `=~`, you should consider overriding `hash`. If instances of your class are ever used as keys in a `Dictionary`, then you should make sure that instances that are considered to be equal have the same hash value:

```python
Complex >> hash
    "Hash is reimplemented because = is implemented."
    ^ real hash bitXor: imaginary hash.
```

Although you should override `=~` and `hash` together, you should *never* override `==`. The semantics of object identity is the same for all classes. `Message ==` is a primitive method of `ProtoObject`.

Note that Pharo has some strange equality behaviour compared to other Smalltalks. For example a symbol and a string can be equal. (We consider this to be a bug, not a feature.)

```python
# 'lulu' = 'lulu'
>>> true
'lulu' = # 'lulu'
>>> true
```

## Class membership

Several methods allow you to query the class of an object.

**class.** You can ask any object about its class using the message `class`.

```python
1 class
>>> SmallInteger
```

**isMemberOf:** Conversely, you can ask if an object is an instance of a specific class:

```python
1 isMemberOf: SmallInteger
>>> true "must be precisely this class"
1 isMemberOf: Integer
>>> false
1 isMemberOf: Number
>>> false
1 isMemberOf: Object
>>> false
```

Since Pharo is written in itself, you can really navigate through its structure using the right combination of superclass and class messages (see Chapter : Classes and Metaclasses).
**isKindOf:**. `Object>>isKindOf:` answers whether the receiver's class is either the same as, or a subclass of the argument class.

```
1 isKindOf: SmallInteger
>>> true
1 isKindOf: Integer
>>> true
1 isKindOf: Number
>>> true
1 isKindOf: Object
>>> true
1 isKindOf: String
>>> false
1/3 isKindOf: Number
>>> true
1/3 isKindOf: Integer
>>> false
```

`1/3` which is a Fraction is a kind of `Number`, since the class `Number` is a super-class of the class `Fraction`, but `1/3` is not an `Integer`.

**respondsTo:**. `Object>>respondsTo:` answers whether the receiver understands the message selector given as an argument.

```
1 respondsTo: #,
>>> false
```

A note on the usage of `respondsTo`. Normally it is a bad idea to query an object for its class, or to ask it which messages it understands. Instead of making decisions based on the class of object, you should simply send a message to the object and let it decide (on the basis of its class) how it should behave. (This concept is sometimes referred to as *duck typing*).

## Copying

Copying objects introduces some subtle issues. Since instance variables are accessed by reference, a *shallow copy* of an object would share its references to instance variables with the original object:

```
a1 := { 'harry' } }.
a1
>>>.#('harry')
a2 := a1 shallowCopy.
a2
>>>.#('harry')
(a1 at: 1) at: 1 put: 'sally'.
a1
>>>.#('sally')
a2
```
## 10.1 Object

```javascript
>>> #(#('sally')) "the subarray is shared!"
```

`Object>>shallowCopy` is a primitive method that creates a shallow copy of an object. Since `a2` is only a shallow copy of `a1`, the two arrays share a reference to the nested `Array` that they contain.

`Object>>deepCopy` makes an arbitrarily deep copy of an object.

```javascript
a1 := { { 'harry' } } .
a2 := a1 deepCopy.
(a1 at: 1) at: 1 put: 'sally'.
a1
>>> #(#('sally'))
a2
>>> #(#(#('harry')))
```

The problem with `deepCopy` is that it will not terminate when applied to a mutually recursive structure:

```javascript
a1 := { 'harry' }.
a2 := { a1 }.
a1 at: 1 put: a2.
a1 deepCopy
>>> !''... does not terminate!''!
```

An alternate solution is to use message copy. It is implemented on `Object` as follows:

```javascript
Object >> copy
    "Answer another instance just like the receiver.
    Subclasses typically override postCopy;
    they typically do not override shallowCopy."
    ^ self shallowCopy postCopy

Object >> postCopy
    ^ self
```

By default `postCopy` returns `self`. It means that by default copy is doing the same as `shallowCopy` but each subclass can decide to customise the `postCopy` method which acts as a hook. You should override `postCopy` to copy any instance variables that should not be shared. In addition there is a good chance that `postCopy` should always do a super `postCopy` to ensure that state of the superclass is also copied.

## Debugging

**halt.** The most important method here is `halt`. To set a breakpoint in a method, simply insert the expression `send self halt` at some point in the body of the method. (Note that since `halt` is defined on `Object` you can also write `1 halt`). When this message is sent, execution will be interrupted and
a debugger will open to this point in your program (See Chapter : The Pharo Environment for more details about the debugger.).

You can also use `Halt` once or `Halt if: aCondition`. Have a look at the class `Halt` which is a special exception.

**assert:** The next most important message is `assert:`, which expects a block as its argument. If the block evaluates to `true`, execution continues. Otherwise an `AssertionFailure` exception will be raised. If this exception is not otherwise caught, the debugger will open to this point in the execution.

`assert:` is especially useful to support *design by contract*. The most typical usage is to check non-trivial pre-conditions to public methods of objects.

`Stack>>pop` could easily have been implemented as follows (Note that this definition is an hypothetical example and not in the Pharo 50 system):

```
Stack >> pop
    "Return the first element and remove it from the stack."

    self assert: [ self isNonEmpty ].
    ^ self linkedList removeFirst element
```

Do not confuse `Object>>assert:` with `Cases>>assert:`, which occurs in the SUnit testing framework (see Chapter : SUnit). While the former expects a block as its argument (actually, it will take any argument that understands value, including a Boolean), the latter expects a Boolean. Although both are useful for debugging, they each serve a very different purpose.

## Error handling

This protocol contains several methods useful for signaling run-time errors.

**deprecated:**. Sending `self deprecated:` signals that the current method should no longer be used, if deprecation has been turned on. You can turn it on/off in the Debugging section using the Settings browser. The argument should describe an alternative. Look for senders of the message `deprecated:` to get an idea.

**doesNotUnderstand:**. `doesNotUnderstand:` (commonly abbreviated in discussions as DNU or MNU) is sent whenever message lookup fails. The default implementation, i.e., `Object>>doesNotUnderstand:` will trigger the debugger at this point. It may be useful to override `doesNotUnderstand:` to provide some other behaviour.

**error.** `Object>>error` and `Object>>error:` are generic methods that can be used to raise exceptions. (Generally it is better to raise your own custom exceptions, so you can distinguish errors arising from your code from those coming from kernel classes.)
**subclassResponsibility.** Abstract methods are implemented by convention with the body `self subclassResponsibility`. Should an abstract class be instantiated by accident, then calls to abstract methods will result in `Object>>subclassResponsibility` being executed.

```python
Object >> subclassResponsibility
    "This message sets up a framework for the behavior of the class'
    subclasses.
    Announce that the subclass should have implemented this message."
    self error: 'My subclass should have overridden ', thisContext
    sender selector printString
```

Magnitude, Number, and Boolean are classical examples of abstract classes that we shall see shortly in this chapter.

```python
Number new + 1
>>> !''Error: My subclass should have overridden #+'''!
```

**shouldNotImplement.** `self shouldNotImplement` is sent by convention to signal that an inherited method is not appropriate for this subclass. This is generally a sign that something is not quite right with the design of the class hierarchy. Due to the limitations of single inheritance, however, sometimes it is very hard to avoid such workarounds.

A typical example is `Collection>>remove`: which is inherited by Dictionary but flagged as not implemented. (A Dictionary provides `removeKey`: instead.)

## Testing

The testing methods have nothing to do with SUnit testing! A testing method is one that lets you ask a question about the state of the receiver and returns a Boolean.

Numerous testing methods are provided by `Object`. There are `isArray`, `isBoolean`, `isBlock`, `isCollection` and so on. Generally such methods are to be avoided since querying an object for its class is a form of violation of encapsulation. Instead of testing an object for its class, one should simply send a request and let the object decide how to handle it.

Nevertheless some of these testing methods are undeniably useful. The most useful are probably `ProtoObject>>isNil` and `Object>>notNil` (though the Null Object design pattern can obviate the need for even these methods).

## Initialize

A final key method that occurs not in `Object` but in `ProtoObject` is `initialize`.
<figure><img src="image_105.png" /><figcaption>**Figure 10.1:** The number hierarchy.</figcaption></figure>

```java
ProtoObject >> initialize
    "Subclasses should redefine this method to perform initializations
     on instance creation"
```

The reason this is important is that in Pharo, the default new method defined for every class in the system will send initialize to newly created instances.

```java
Behavior >> new
    "Answer a new initialized instance of the receiver (which is a
     class) with no indexable
     variables. Fail if the class is indexable."
    ^ self basicNew initialize
```

This means that simply by overriding the initialize hook method, new instances of your class will automatically be initialized. The initialize method should normally perform a super initialize to establish the class invariant for any inherited instance variables.

## 10.2 Numbers

Numbers in Pharo are not primitive data values but true objects. Of course numbers are implemented efficiently in the virtual machine, but the Number hierarchy is as perfectly accessible and extensible as any other portion of the class hierarchy.

The abstract root of this hierarchy is Magnitude, which represents all kinds of classes supporting comparison operators. Number adds various arithmetic and other operators as mostly abstract methods. Float and Fraction represent,
respectively, floating point numbers and fractional values. `Float` subclasses (`BoxedFloat64` and `SmallFloat64`) represent `Float` on certain architectures. For example `BoxedFloat64` is only available for 64 bit systems. `Integer` is also abstract, thus distinguishing between subclasses `SmallInteger`, `LargePositiveInteger` and `LargeNegativeInteger`. For the most part, users do not need to be aware of the difference between the three `Integer` classes, as values are automatically converted as needed.

## Magnitude

`Magnitude` is the parent not only of the `Number` classes, but also of other classes supporting comparison operations, such as `Character`, `Duration` and `Timespan`.

Methods `<` and `=`, are abstract. The remaining operators are generically defined. For example:

```
Magnitude >> < aMagnitude
    "Answer whether the receiver is less than the argument."

    ^ self subclassResponsibility

Magnitude >> > aMagnitude
    "Answer whether the receiver is greater than the argument."

    ^ aMagnitude < self
```

## Number

Similarly, `Number` defines `+`, `-`, `*` and `/` to be abstract, but all other arithmetic operators are generically defined.

All `Number` objects support various *converting operators*, such as `asFloat` and `asInteger`. There are also numerous *shortcut constructor methods* which generate `Durations`, such as `hour`, `day` and `week`.

`Numbers` directly support common `math functions` such as `sin`, `log`, `raiseTo`, `squared`, `sqrt` and so on.

The method `Number>>printOn:` is implemented in terms of the abstract method `Number>>printOn:base:`. (The default base is 10.)

Testing methods include `even`, `odd`, `positive` and `negative`. Unsurprisingly `Number` overrides `isNumber`. More interestingly, `isInfinite` is defined to return `false`.

*Truncation* methods include `floor`, `ceiling`, `integerPart`, `fractionPart` and so on.

```
1 + 2.5
>>> 3.5 "Addition of two numbers"
```
3.4 * 5
>>> 17.0 "Multiplication of two numbers"

8 / 2
>>> 4 "Division of two numbers"

10 - 8.3
>>> 1.7 "Subtraction of two numbers"

12 = 11
>>> false "Equality between two numbers"

12 =~ 11
>>> true "Test if two numbers are different"

12 > 9
>>> true "Greater than"

12 >= 10
>>> true "Greater or equal than"

12 < 10
>>> false "Smaller than"

100@10
>>> 100@10 "Point creation"

The following example works surprisingly well in Pharo:

1000 factorial / 999 factorial
>>> 1000

Note that 1000 factorial is really calculated, which in many other languages can be quite difficult to compute. This is an excellent example of automatic coercion and exact handling of a number.

**To do** Try to display the result of 1000 factorial. It takes more time to display it than to calculate it!

## Float

Float implements the abstract Number methods for floating point numbers.

More interestingly, Float class (i.e., the class-side of Float) provides methods to return the following constants: e, infinity, nan and pi.

Float pi
>>> 3.141592653589793

Float infinity
>>> Infinity

Float infinity isInfinite
>>> true
Fraction

Fractions are represented by instance variables for the numerator and de-
nominator, which should be Integers. Fractions are normally created by
Integer division (rather than using the constructor method Fraction>>nu-
merator:denominator:):

6/8
>>> (3/4)
(6/8) class
>>> Fraction

Multiplying a Fraction by an Integer or another Fraction may yield an
Integer:

6/8 * 4
>>> 3

Integer

Integer is the abstract parent of three concrete integer implementations.
In addition to providing concrete implementations of many abstract Number
methods, it also adds a few methods specific to integers, such as factorial,
atRandom, isPrime, gcd: and many others.

SmallInteger is special in that its instances are represented compactly —
instead of being stored as a reference, a SmallInteger is represented directly
using the bits that would otherwise be used to hold a reference. The first bit
of an object reference indicates whether the object is a SmallInteger or not.
Now the virtual machine abstracts that from you, therefore you cannot see
this directly when inspecting the object.

The class methods minVal and maxVal tell us the range of a SmallInteger:

SmallInteger maxVal = ((2 raisedTo: 30) - 1)
>>> true

SmallInteger minVal = (2 raisedTo: 30) negated
>>> true

When a SmallInteger goes out of this range, it is automatically converted to a
LargePositiveInteger or a LargeNegativeInteger, as needed:

(SmallInteger maxVal + 1) class
>>> LargePositiveInteger
(SmallInteger minVal - 1) class
>>> LargeNegativeInteger

Large integers are similarly converted back to small integers when appropri-
ate.
As in most programming languages, integers can be useful for specifying
iterative behaviour. There is a dedicated method `timesRepeat:` for evaluating
a block repeatedly. We have already seen a similar example in Chapter :
Syntax in a Nutshell.

```
| n |
n := 2.
3 timesRepeat: [ n := n * n ].
n
>>> 256
```

## 10.3 Characters

Character is defined a subclass of Magnitude. Printable characters are represented in Pharo as `$<char>`. For example:

```
$a < $b
>>> true
```

Non-printing characters can be generated by various class methods. Character `class>>value:` takes the Unicode (or ASCII) integer value as argument and returns the corresponding character. The protocol accessing untypable characters contains a number of convenience constructor methods such as backspace, `cr`, escape, `euro`, space, `tab`, and so on.

```
Character space = (Character value: Character space asciiValue)
>>> true
```

The `printOn:` method is clever enough to know which of the three ways to generate characters offers the most appropriate representation:

```
Character value: 1
>>> Character home

Character value: 2
>>> Character value: 2

Character value: 32
>>> Character space

Character value: 97
>>> $a
```

Various convenient testing methods are built in: `isAlphaNumeric`, `isChar`, `isDigit`, `isLowercase`, `isVowel`, and so on.

To convert a Character to the string containing just that character, send `asString`. In this case `asString` and `printString` yield different results:

```
$a asString
>>> 'a'
```
<figure><img src="image_106.png" /><figcaption>Figure 10.2: The String Hierarchy.</figcaption></figure>

```
$\a
>>> $a
$\a printString
>>> '$a'
```

Like `SmallInteger`, a `Character` is an immediate value not an object reference. Most of the time you won't see any difference and can use objects of class `Character` like any other too. But this means, equal value characters are always *identical*:

```
(Character value: 97) == $a
>>> true
```

## 10.4 Strings

A `String` is an indexed `Collection` that holds only `Characters`.

In fact, `String` is abstract and `Pharo` strings are actually instances of the concrete class `ByteString`.

```
'hello world' class
>>> ByteString
```

The other important subclass of `String` is `Symbol`. The key difference is that there is only ever a single instance of `Symbol` with a given value. (This is sometimes called the *unique instance property*). In contrast, two separately constructed `Strings` that happen to contain the same sequence of characters will often be different objects.
```python
    ['hel', 'lo' == 'hello'
    >>> false

    ('hel', 'lo') asSymbol == #hello
    >>> true
```

Another important difference is that a `String` is mutable, whereas a `Symbol` is immutable.

```python
    'hello' at: 2 put: $u; yourself
    >>> 'hullo'

    #hello at: 2 put: $u
    >>> error!
```

It is easy to forget that since strings are collections, they understand the same messages that other collections do:

```python
    #hello indexOf: $o
    >>> 5
```

Although `String` does not inherit from `Magnitude`, it does support the usual comparing methods, `<`, `=`, and so on. In addition, `String>>match:` is useful for some basic glob-style pattern-matching:

```python
    '*or*' match: 'zorro'
    >>> true
```

Regular expressions will be discussed in more detail in Chapter: Regular Expressions in Pharo.

Strings support a rather large number of conversion methods. Many of these are shortcut constructor methods for other classes, such as `asDate`, `asInteger` and so on. There are also a number of useful methods for converting a string to another string, such as `capitalized` and `translateToLowercase`.

For more on strings and collections, see Chapter: Collections.

## 10.5 Booleans

The class `Boolean` offers a fascinating insight into how much of the Pharo language has been pushed into the class library. `Boolean` is the abstract superclass of the singleton classes `True` and `False`.

Most of the behaviour of `Booleans` can be understood by considering the method `ifTrue`: `ifFalse`:, which takes two `Blocks` as arguments.

```python
    4 factorial > 20
        ifTrue: [ 'bigger' ]
        ifFalse: [ 'smaller' ]
    >>> 'bigger'
```
<figure><img src="image_107.png" /><figcaption>**Figure 10.3:** The Boolean Hierarchy.</figcaption></figure>

The method `ifTrue:ifFalse:` is abstract in class `Boolean`. The implementations in its concrete subclasses are both trivial:

```
True >> ifTrue: trueAlternativeBlock ifFalse: falseAlternativeBlock
^ trueAlternativeBlock value

False >> ifTrue: trueAlternativeBlock ifFalse: falseAlternativeBlock
^ falseAlternativeBlock value
```

Each of them execute the correct block depending on the receiver of the message. In fact, this is the essence of OOP: when a message is sent to an object, the object itself determines which method will be used to respond. In this case an instance of `True` simply executes the `true` alternative, while an instance of `False` executes the `false` alternative. All the abstract Boolean methods are implemented in this way for `True` and `False`. For example the implementation of negation (message `not`) is defined the same way:

```
True >> not
"Negation--answer false since the receiver is true."
^ false

False >> not
"Negation--answer true since the receiver is false."
^ true
```

Booleans offer several useful convenience methods, such as `ifTrue:`, `if-False:`, and `ifFalse:ifTrue`. You also have the choice between eager and lazy conjunctions and disjunctions.

```
( 1 > 2 ) & ( 3 < 4 )
>>> false "Eager, must evaluate both sides"

( 1 > 2 ) and: [ 3 < 4 ]
>>> false "Lazy, only evaluate receiver"

( 1 > 2 ) and: [ ( 1 / 0 ) > 0 ]
>>> false "Argument block is never executed, so no exception"
```
In the first example, both Boolean subexpressions are executed, since & takes a Boolean argument. In the second and third examples, only the first is executed, since and: expects a Block as its argument. The Block is executed only if the first argument is true.

**To do** Try to imagine how and: and or: are implemented. Check the implementations in Boolean, True and False.

## 10.6 Chapter summary

* If you override = then you should override hash as well.

* Override postCopy to correctly implement copying for your objects.

* Use self halt. to set a breakpoint.

* Return self subclassResponsibility to make a method abstract.

* To give an object a String representation you should override printOn:.

* Override the hook method initialize to properly initialize instances.

* Number methods automatically convert between Floats, Fractions and Integers.

* Fractions truly represent rational numbers rather than floats.

* All Characters are like unique instances.

* Strings are mutable; Symbols are not. Take care not to mutate string literals, however!

* Symbols are unique; Strings are not.

* Strings and Symbols are Collections and therefore support the usual Collection methods.
CHAPTER 11

Collections

11.1 Introduction

The collection classes form a loosely-defined group of general-purpose sub-
classes of *Collection* and *Stream*. Many of these (like *Bitmap*, *FileStream* and *CompiledMethod*) are special-purpose classes crafted for use in other parts
of the system or in applications, and hence not categorized as *Collections* by
the system organization. For the purposes of this chapter, we use the term
*Collection Hierarchy* to mean *Collection* and its subclasses that are also in the
packages labelled *Collections-*\*. We use the term *Stream Hierarchy* to mean
*Stream* and its subclasses that are also in the *Collections-Streams* packages.

In this chapter we focus mainly on the subset of collection classes shown in
Figure 11.1. Streams will be discussed separately in Chapter : Streams.

11.2 The varieties of collections

To make good use of the collection classes, the reader needs at least a super-
ficial knowledge of the wide variety of collections that they implement, and
their commonalities and differences.

Programming with collections using high-order functions rather than individ-
ual elements is an important way to raise the level of abstraction of a program.
The Lisp function map, which applies an argument function to every element
of a list and returns a new list containing the results is an early example of
this style. Following its Smalltalk root, Pharo adopts this collection-based
high-order programming as a central tenet. Modern functional programming
languages such as ML and Haskell have followed Smalltalk's lead.
<figure><img src="image_108.png" /><figcaption>**Figure 11.1:** Some of the key collection classes in Pharo.</figcaption></figure>

Why is this a good idea? Suppose you have a data structure containing a collection of student records, and wish to perform some action on all of the students that meet some criterion. Programmers raised to use an imperative language will immediately reach for a loop. But the Pharo programmer will write:

```
[ students
  select: [ :each | each gpa < threshold ]
]
```

This expression returns a new collection containing precisely those elements of *students* for which the block (the bracketed function) returns true. The block can be thought of as a lambda-expression defining an anonymous function *x*. *x* gpa < threshold. This code has the simplicity and elegance of a domain-specific query language.

The message *select:* is understood by *all* collections in Pharo. There is no need to find out if the student data structure is an array or a linked list: the *select:* message is understood by both. Note that this is quite different from using a loop, where one must know whether *students* is an array or a linked list before the loop can be set up.

In Pharo, when one speaks of a collection without being more specific about the kind of collection, one means an object that supports well-defined protocols for testing membership and enumerating the elements. *All* collections understand the testing messages *includes:*, *empty* and *occurrencesOf*. *All* collections understand the enumeration messages *do:*, *select:*, *reject*: (which is the opposite of *select:*) , *collect*: (which is like Lisp's *map*), *detect:ifNone:*, *inject:into*: (which performs a left fold) and many more. It
is the ubiquity of this protocol, as well as its variety, that makes it so powerful.

The table below summarizes the standard protocols supported by most of the classes in the collection hierarchy. These methods are defined, redefined, optimized or occasionally even forbidden by subclasses of `Collection`.

<table><thead><tr><td>Protocol</td><td>Methods</td></tr></thead><tbody><tr><td>accessing</td><td>size, capacity, at:, at:put:</td></tr><tr><td>testing</td><td>empty, includes:, contains:, occurrencesOf:</td></tr><tr><td>adding</td><td>add:, addAll:</td></tr><tr><td>removing</td><td>remove:, remove:ifAbsent:, removeAll:</td></tr><tr><td>enumerating</td><td>do:, collect:, select:, reject:<br>detect:, detect:ifNone:, inject:into:</td></tr><tr><td>converting</td><td>asBag, asSet, asOrderedCollection, asSortedCollection,<br>asArray, asSortedCollection:</td></tr><tr><td>creation</td><td>with:, with:with:, with:with:with:, with:with:with:with:, with:with:with:with:with:withAll:</td></tr></tbody></table>

Beyond this basic uniformity, there are many different kinds of collection either supporting different protocols, or providing different behaviour for the same requests. Let us briefly survey some of the key differences:

**Sequenceable**: Instances of all subclasses of `SequenceableCollection` start from a first element and proceed in a well-defined order to a last element. Instances of `Set`, `Bag` and `Dictionary`, on the other hand, are not sequenceable.

**Sortable**: A `SortedCollection` maintains its elements in sort order.

**Indexable**: Most sequenceable collections are also indexable, that is, elements can be retrieved with message `at: anIndex`. `Array` is the familiar indexable data structure with a fixed size; `anArray at: n` retrieves the nth element of `anArray`, and `anArray at: n put: v` changes the nth element to `v`. `LinkedLists` and `SkipLists` are sequenceable but not indexable, that is, they understand first and last, but not the message `at:`.

**Keyed**: Instances of `Dictionary` and its subclasses are accessed by keys instead of indices.

**Mutable**: Most collections are mutable, but `Intervals` and `Symbols` are not. An `Interval` is an immutable collection representing a range of integers. For example, `5 to: 16 by: 2` is an interval that contains the elements 5, 7, 9, 11, 13 and 15. It is indexable with message `at: anIndex`, but cannot be changed with message `at: anIndex put: aValue`.

**Growable**: Instances of `Interval` and `Array` are always of a fixed size. Other kinds of collections (sorted collections, ordered collections, and linked lists) can grow after creation. The class `OrderedCollection` is more
<figure><img src="image_109.png" /><figcaption>**Figure 11.2:** Some collection classes categorized by implementation technique.</figcaption></figure>

general than `Array`; the size of an `OrderedCollection` grows on demand, and it defines messages `addFirst`: `anElement` and `addLast`: `anElement` as well as messages at: `anIndex` and at: `anIndex` put: `aValue`.

**Accepts duplicates:** A `Set` filters out duplicates, but a `Bag` does not. Classes `Dictionary`, `Set` and `Bag` use the `=` method provided by the elements; the `Identity` variants of these classes use the `==` method, which tests whether the arguments are the same object, and the `Pluggable` variants use an arbitrary equivalence relation supplied by the creator of the collection.

**Heterogeneous:** Most collections will hold any kind of element. A `String`, `CharacterArray` or `Symbol`, however, only holds `Characters`. An `Array` will hold any mix of objects, but a `byteArray` only holds `Bytes`. A `LinkedInList` is constrained to hold elements that conform to the `Link` accessing protocol.

## 11.3 Collection implementations

These categorizations by functionality are not our only concern; we must also consider how the collection classes are implemented. As shown in Figure 11.2, five main implementation techniques are employed.

* Arrays store their elements in the (indexable) instance variables of the collection object itself; as a consequence, arrays must be of a fixed size, but can be created with a single memory allocation.

* `OrderedCollections` and `SortedCollections` store their elements in an array that is referenced by one of the instance variables of the collection. Consequently, the internal array can be replaced with a larger one if the collection grows beyond its storage capacity.

* The various kinds of `set` and `dictionary` also reference a subsidiary array for storage, but use the array as a hash table. `Bags` use a subsidiary
11.4 Examples of key classes

Dictionary, with the elements of the bag as keys and the number of
occurrences as values.

* `LinkedLists` use a standard singly-linked representation.

* Intervals are represented by three integers that record the two end-points and the step size.

In addition to these classes, there are also weak variants of `Array`, `Set` and of the various kinds of dictionary. These collections hold onto their elements weakly, i.e., in a way that does not prevent the elements from being garbage collected. The Pharo virtual machine is aware of these classes and handles them specially.

11.4 Examples of key classes

We present now the most common or important collection classes using
simple code examples. The main protocols of collections are:

* `messages at:`, `at:put`: — to access an element,

* `messages add:`, `remove`: — to add or remove an element,

* `messages size`, `empty?`, `include`: — to get some information about the collection,

* `messages do:`, `collect:`, `select`: — to iterate over the collection.

Each collection may implement (or not) such protocols, and when they do,
they interpret them to fit with their semantics. We suggest you browse the
classes themselves to identify specific and more advanced protocols.

We will focus on the most common collection classes: `OrderedCollection`, `Set`, `SortedCollection`, `Dictionary`, `Interval`, and `Array`.

**Common creation protocol.** There are several ways to create instances of collections. The most generic ones use the message `new: aSize` and with: `anElement`.

* `new: anInteger` creates a collection of size `anInteger` whose elements will all be `nil`.

* `with: anObject` creates a collection and adds `anObject` to the created collection.

Different collections will realize this behaviour differently.

You can create collections with initial elements using the methods `with:`, `with:with: etc.` for up to six elements.

```
Array with: 1
>>> #(1)
```
```
Array with: 1 with: 2
>>> #(1 2)

Array with: 1 with: 2 with: 3
>>> #(1 2 3)

Array with: 1 with: 2 with: 3 with: 4
>>> #(1 2 3 4)

Array with: 1 with: 2 with: 3 with: 4 with: 5
>>> #(1 2 3 4 5)

Array with: 1 with: 2 with: 3 with: 4 with: 5 with: 6
>>> #(1 2 3 4 5 6)
```

You can also use message addAll: aCollection to add all elements of one kind of collection to another kind:

```
(1 to: 5) asOrderedCollection addAll: '678'; yourself
>>> an OrderedCollection(1 2 3 4 5 6 7 8)
```

Take care that addAll: returns its argument, and not the receiver!

You can also create many collections with withAll: aCollection.

```
Array withAll: #(7 3 1 3)
>>> #(7 3 1 3)

OrderedCollection withAll: #(7 3 1 3)
>>> an OrderedCollection(7 3 1 3)

SortedCollection withAll: #(7 3 1 3)
>>> a SortedCollection(1 3 3 7)

Set withAll: #(7 3 1 3)
>>> a Set(7 1 3)

Bag withAll: #(7 3 1 3)
>>> a Bag(7 1 3 3)
```

## Array

An Array is a fixed-sized collection of elements accessed by integer indices. Contrary to the C convention in Pharo, the first element of an array is at position 1 and not 0. The main protocol to access array elements is the method `at:` and `at:put:.` at: anInteger returns the element at index anInteger. `at:` anInteger `put:` anObject puts anObject at index anInteger. Arrays are fixed-size collections therefore we cannot add or remove elements at the end of an array. The following code creates an array of size 5, puts values in the first 3 locations and returns the first element.

```
| anArray |
anArray := Array new: 5.
anArray at: 1 put: 4.
```
11.4 Examples of key classes

anArray at: 2 put: 3/2.
anArray at: 3 put: 'ssss'.
anArray at: 1
>>> 4

There are several ways to create instances of the class Array. We can use new:, with:, and the constructs #() (literal arrays) and { . } (dynamic compact syntax).

**Creation with new:** The message new: anInteger creates an array of size anInteger. Array new: 5 creates an array of size 5. (Note: the value of each element is initialized to nil).

**Creation using with:** The with:* messages allow one to specify the value of the elements. The following code creates an array of three elements consisting of the number 4, the fraction 3/2 and the string 'lulu'.

Array with: 4 with: 3/2 with: 'lulu'
>>> {4. (3/2). 'lulu'}

**Literal creation with #()** The expression #() creates literal arrays with constants or *literal* elements that have to be known when the expression is compiled, and not when it is executed. The following code creates an array of size 2 where the first element is the (literal) number 1 and the second the (literal) string 'here'.

#(1 'here') size
>>> 2

Now, if you execute the expression #(1+2), you do not get an array with a single element 3 but instead you get the array #(1 #+ 2) i.e., with three elements: 1, the symbol #+ and the number 2.

#(1+2)
>>> #(1 #+ 2)

This occurs because the construct #() does not execute the expressions it contains. The elements are only objects that are created when parsing the expression (called literal objects). The expression is scanned and the resulting elements are fed to a new array. Literal arrays contain numbers, nil, true, false, symbols, strings and other literal arrays. During the execution of #() expressions, there are no messages sent.

**Dynamic creation with { . }** Finally, you can create a dynamic array using the construct { . }. The expression { a . b } is totally equivalent to Array with: a with: b. This means in particular that the expressions enclosed by { and } are executed (contrary to the case of #())
```groovy
[
    { 1 + 2 }
    >>> #(3)

    {(1/2) asFloat} at: 1
    >>> 0.5

    {10 atRandom. 1/3} at: 2
    >>> (1/3)
```

**Element Access** Elements of all sequenceable collections can be accessed with messages at: anIndex and at: anIndex put: anObject.

```groovy
[
    | anArray |
    anArray := #(1 2 3 4 5 6) copy.
    anArray at: 3 >>> 3
    anArray at: 3 put: 33.
    anArray at: 3
    >>> 33
```

Be careful: as a general principle do not modify literal arrays! Literal arrays are kept in compiled method literal frames (a space where literals appearing in a method are stored), therefore unless you copy the array, the second time you execute the code your *literal* array may not have the value you expect. In the example, without copying the array, the second time around, the literal `(1 2 3 4 5 6)` will actually be `(1 2 33 4 5 6)`. Dynamic arrays do not have this problem because they are not stored in literal frames.

## OrderedCollection

OrderedCollection is one of the collections that can grow, and to which elements can be added sequentially. It offers a variety of messages such as `add:`, `addFirst:`, `addLast:`, and `addAll:.`

```groovy
[
    | ordCol |
    ordCol := OrderedCollection new.
    ordCol add: 'Seaside'; add: 'SmalltalkHub'; addFirst: 'Monticello'.
    ordCol
    >>> an OrderedCollection('Monticello' 'Seaside' 'SmalltalkHub')
```

**Removing Elements** The message `remove: anObject` removes the first occurrence of an object from the collection. If the collection does not include such an object, it raises an error.

```groovy
ordCol add: 'Monticello'.
ordCol remove: 'Monticello'.
ordCol
>>> an OrderedCollection('Seaside' 'SmalltalkHub' 'Monticello')
```
There is a variant of `remove`: `named remove`: `ifAbsent`: that allows one to specify as second argument a block that is executed in case the element to be removed is not in the collection.

```clojure
result := ordCol remove: 'zork' ifAbsent: [33].
result
>>> 33
```

**Conversion** It is possible to get an OrderedCollection from an Array (or any other collection) by sending the message `asOrderedCollection`:

```clojure
#(1 2 3) asOrderedCollection
>>> an OrderedCollection(1 2 3)

'hello' asOrderedCollection
>>> an OrderedCollection($h $e $l $l $o)
```

## Interval

The class `Interval` represents ranges of numbers. For example, the interval of numbers from 1 to 100 is defined as follows:

```clojure
Interval from: 1 to: 100
>>> (1 to: 100)
```

The result of `printString` reveals that the class `Number` provides us with a convenience method called `to:` to generate intervals:

```clojure
(Interval from: 1 to: 100) = (1 to: 100)
>>> true
```

We can use `Interval class>>from:to:by` or `Number>>to:by` to specify the step between two numbers as follows:

```clojure
(Interval from: 1 to: 100 by: 0.5) size
>>> 199
```

```clojure
(1 to: 100 by: 0.5) at: 198
>>> 99.5
```

```clojure
(1/2 to: 54/7 by: 1/3) last
>>> (15/2)
```

## Dictionary

Dictionaries are important collections whose elements are accessed using keys. Among the most commonly used messages of dictionary you will find `at`: `aKey`, `at`: `aKey put`: `aValue`, `at`: `aKey ifAbsent`: `aBlock`, `keys`, and `values`.

```clojure
| colors |
colors := Dictionary new.
```
```groovy
colors at: #yellow put: Color yellow.
colors at: #blue put: Color blue.
colors at: #red put: Color red.
colors at: #yellow
>>> Color yellow
colors keys
>>> #red #blue #yellow
colors values
>>> {Color blue . Color yellow . Color red}
```

Dictionaries compare keys by equality. Two keys are considered to be the same if they return true when compared using `==`. A common and difficult to spot bug is to use as key an object whose `==` method has been redefined but not its hash method. Both methods are used in the implementation of dictionary and when comparing objects.

In its implementation, a `Dictionary` can be seen as consisting of a set of (key value) associations created using the message `->`. We can create a `Dictionary` from a collection of associations, or we may convert a dictionary to an array of associations.

```groovy
| colors |
colors := Dictionary newFrom: { #blue->Color blue . #red->Color red .
                                #yellow->Color yellow }.
colors removeKey: #blue.
colors associations
>>> {#yellow->Color yellow. #red->Color red}
```

**IdentityDictionary** While a dictionary uses the result of the messages `==` and `hash` to determine if two keys are the same, the class `IdentityDictionary` uses the identity (message `==`) of the key instead of its values, i.e., it considers two keys to be equal *only* if they are the same object.

Often `Symbols` are used as keys, in which case it is natural to use an `IdentityDictionary`, since a `Symbol` is guaranteed to be globally unique. If, on the other hand, your keys are `Strings`, it is better to use a plain `Dictionary`, or you may get into trouble:

```groovy
a := 'foobar'.
b := a copy.
trouble := IdentityDictionary new.
trouble at: a put: 'a'; at: b put: 'b'.
trouble at: a
>>> 'a'
trouble at: b
>>> 'b'
trouble at: 'foobar'
>>> 'a'
```
Since a and b are different objects, they are treated as different objects. Interestingly, the literal `'foobar'` is allocated just once, so is really the same object as a. You don't want your code to depend on behaviour like this! A plain `Dictionary` would give the same value for any key equal to `'foobar'`.

Use only globally unique objects (like `Symbols` or `SmallIntegers`) as keys for an `IdentityDictionary`, and `Strings` (or other objects) as keys for a plain `Dictionary`.

Note that the expression `Smalltalk globals` returns an instance of `System-Dictionary`, a subclass of `IdentityDictionary`, hence all its keys are `Symbols` (actually, `ByteSymbols`, which contain only 8-bit characters).

```
[Smalltalk globals keys collect: [ :each | each class] as:Set
>>> a Set(byteSymbol)
```

Here we are using `collect:as:` to specify the result collection to be of class `Set`, that way we collect each kind of class used as a key only once.

## Set

The class `Set` is a collection which behaves as a mathematical set, i.e., as a collection with no duplicate elements and without any order. In a `Set`, elements are added using the message `add:` and they cannot be accessed using the message `at:`. Objects put in a set should implement the methods `hash` and `==`.

```
[ s := Set new.
  s add: 4/2; add: 4; add:2.
  s size
>>> 2
```

You can also create sets using `Set class>>newFrom:` or the conversion message `Collection>>asSet`:

```
[ (Set newFrom: #( 1 2 3 1 4 )) = #(1 2 3 4 3 2 1) asSet
>>> true
```

`asSet` offers us a convenient way to eliminate duplicates from a collection:

```
[ { Color black. Color white. (Color red + Color blue + Color green) }
  asSet size
>>> 2
```

Note that `red + blue + green = white`.

A `Bag` is much like a `Set` except that it does allow duplicates:

```
[ { Color black. Color white. (Color red + Color blue + Color green) }
  asBag size
>>> 3
```
The set operations `union`, `intersection` and `membership test` are implemented by the Collection messages `union:`, `intersection:`, and `includes:`. The receiver is first converted to a Set, so these operations work for all kinds of collections!

```groovy
(1 to: 6) union: (4 to: 10)
>>> a Set(1 2 3 4 5 6 7 8 9 10)

'hello' intersection: 'there'
>>> 'he'

#Smalltalk includes: $k
>>> true
```

As we explain below, elements of a set are accessed using iterators (see Section 11.5).

## SortedCollection

In contrast to an OrderedCollection, a SortedCollection maintains its elements in sort order. By default, a sorted collection uses the message `<=`, to establish sort order, so it can sort instances of subclasses of the abstract class Magnitude, which defines the protocol of comparable objects (`<`, `>=`, `>=`, between: and: ...). (See Chapter: Basic Classes).

You can create a SortedCollection by creating a new instance and adding elements to it:

```groovy
SortedCollection new add: 5; add: 2; add: 50; add: -10; yourself.
>>> a SortedCollection(-10 2 5 50)
```

More usually, though, one will send the conversion message `asSortedCollection` to an existing collection:

```groovy
#(5 2 50 -10) asSortedCollection
>>> a SortedCollection(-10 2 5 50)
```

```groovy
'hello' asSortedCollection
>>> a SortedCollection($e $h $l $l $o)
```

How do you get a String back from this result? `asString` unfortunately returns the `printString` representation, which is not what we want:

```groovy
'hello' asSortedCollection asString
>>> 'a' SortedCollection($e $h $l $l $o)
```

The correct answer is to either use `String class>>newFrom:`, `String class>>with-All:` or `Object>>as`:

```groovy
'hello' asSortedCollection as: String
>>> 'ehllo'
String newFrom: 'hello' asSortedCollection
>>> 'ehllo'
```
```groovy
String withAll: 'hello' asSortedCollection
>>> 'ehllo'
```

It is possible to have different kinds of elements in a SortedCollection as long as they are all comparable. For example, we can mix different kinds of numbers such as integers, floats and fractions:

```groovy
{ 5 . 2 / -3 . 5.21 } asSortedCollection
>>> a SortedCollection((-2/3) 5 5.21)
```

Imagine that you want to sort objects that do not define the method `<=` or that you would like to have a different sorting criterion. You can do this by supplying a two argument block, called a sortblock, to the sorted collection. For example, the class `Color` is not a `Magnitude` and it does not implement the method `<=`, but we can specify a block stating that the colors should be sorted according to their luminance (a measure of brightness).

```groovy
col := SortedCollection
    sortBlock: [ :c1 :c2 | c1 luminance <= c2 luminance ].
col addAll: { Color red . Color yellow . Color white . Color black }.
col
>>> a SortedCollection(Color black Color red Color yellow Color white)
```

## String

In Pharo, a `String` is a collection of Characters. It is sequenceable, indexable, mutable and homogeneous, containing only `Character` instances. Like Arrays, `String`s have a dedicated syntax, and are normally created by directly specifying a `String` literal within single quotes, but the usual collection creation methods will work as well.

```groovy
'Hello'
>>> 'Hello'
```

```groovy
String with: $A
>>> 'A'
```

```groovy
String with: $h with: $i with: $!
>>> 'hi!'
```

```groovy
String newFrom: #($h $e $l $l $o)
>>> 'hello'
```

In actual fact, `String` is abstract. When we instantiate a `String` we actually get either an 8-bit `ByteString` or a 32-bit `WideString`. To keep things simple, we usually ignore the difference and just talk about instances of `String`.

While strings are delimited by single quotes, a string can contain a single quote: to define a string with a single quote we should type it twice. Note that the string will contain only one element and not two as shown below:
```groovy
[
    'l' 'idiot' at: 2
>>> $

    'l' 'idiot' at: 3
>>> $i
```

Two instances of `String` can be concatenated with a comma.

```groovy
s := 'no', ' ', 'worries'.
s
>>> 'no worries'
```

Since a string is a mutable collection we can also change it using the message `at:put:.`.

```groovy
s at: 4 put: $h; at: 5 put: $u.
s
>>> 'no hurries'
```

Note that the comma method is defined by `Collection`, so it will work for any kind of collection!

```groovy
(1 to: 3), '45'
>>> #(1 2 3 $4 $5)
```

We can also modify an existing string using `replaceAll:with:` or `replace-From:to:with:` as shown below. Note that the number of characters and the interval should have the same size.

```groovy
s replaceAll: $n with: $N.
s
>>> 'No hurries'
s replaceFrom: 4 to: 5 with: 'wo'.
s
>>> 'No worries'
```

In contrast to the methods described above, the method `copyReplaceAll`: creates a new string. (Curiously, here the arguments are substrings rather than individual characters, and their sizes do not have to match.)

```groovy
s copyReplaceAll: 'uries' with: 'mbats'
>>> 'No wombats'
```

A quick look at the implementation of these methods reveals that they are defined not only for `Strings`, but for any kind of `SequenceableCollection`, so the following also works:

```groovy
(1 to: 6) copyReplaceAll: (3 to: 5) with: { 'three' . 'etc.' }
>>> #(1 2 'three' 'etc.' 6)
```

**String matching** It is possible to ask whether a pattern matches a string by sending the match: message. The pattern can use `*` to match an arbitrary
series of characters and # to match a single character. Note that match: is sent to the pattern and not the string to be matched.

```python
'Linux *' match: 'Linux mag'
>>> true
'GNU#Linux #ag' match: 'GNU/Linux tag'
>>> true
```

More advanced pattern matching facilities are also available in the Regex package.

**Substrings** For substring manipulation we can use messages like first, first:, allButFirst:, copyFrom:to: and others, defined in Sequence-ableCollection.

```python
'alphabet' at: 6
>>> $b
'alphabet' first
>>> $a
'alphabet' first: 5
>>> 'alpha'
'alphabet' allButFirst: 3
>>> 'habet'
'alphabet' copyFrom: 5 to: 7
>>> 'abe'
'alphabet' copyFrom: 3 to: 3
>>> 'p' (not $p)
```

Be aware that result type can be different, depending on the method used. Most of the substring-related methods return String instances. But the messages that always return one element of the String collection, return a Character instance (for example, 'alphabet' at: 6 returns the character $b). For a complete list of substring-related messages, browse the Sequence-ableCollection class (especially the accessing protocol).

**Some tests on strings** The following examples illustrate the use of empty, includes: and anySatisfy: which are also messages defined not only on Strings but more generally on collections.

```python
'Hello' empty
>>> false
'Hello' includes: $a
>>> false
'JOE' anySatisfy: [ :c | c isLowercase ]
>>> false
```
'Joe' anySatisfy: [ :c | c isLowercase ]
>>> true

**String templating** There are three messages that are useful to manage string templating: `format:`, `expandMacros` and `expandMacrosWith`.

'{1} is {2}' format: {'Pharo' . 'cool'}
>>> 'Pharo is cool'

The messages of the `expandMacros` family offer variable substitution, using `<n>` for carriage return, `<t>` for tabulation, `<1s>`, `<2s>`, `<3s>` for arguments (`<1p>`, `<2p>`, surrounds the string with single quotes), and `<1?value1:value2>` for conditional.

'look-<t>-here' expandMacros
>>> 'look- -here'

'<1s> is <2s>' expandMacrosWith: 'Pharo' with: 'cool'
>>> 'Pharo is cool'

'<2s> is <1s>' expandMacrosWith: 'Pharo' with: 'cool'
>>> 'cool is Pharo'

'<1p> or <1s>' expandMacrosWith: 'Pharo' with: 'cool'
>>> ''Pharo'' or Pharo'

'<1?Quentin:Thibaut> plays' expandMacrosWith: true
>>> 'Quentin plays'

'<1?Quentin:Thibaut> plays' expandMacrosWith: false
>>> 'Thibaut plays'

**Some other utility methods** The class `String` offers numerous other utilities including the messages `asLowercase`, `asUppercase` and `capitalized`.

'XYZ' asLowercase
>>> 'xyz'

'xyz' asUppercase
>>> 'XYZ'

'hilaire' capitalized
>>> 'Hilaire'

'Hilaire' uncapitalized
>>> 'hilaire'

'1.54' asNumber
>>> 1.54

'this sentence is without a doubt far too long' contractTo: 20
>>> 'this sent...too long'
Note that there is generally a difference between asking an object its string representation by sending the message `printString` and converting it to a string by sending the message `asString`. Here is an example of the difference.

```python
#ASymbol printString
>>> '#ASymbol'
```

```python
#ASymbol asString
>>> 'ASymbol'
```

A symbol is similar to a string but is guaranteed to be globally unique. For this reason symbols are preferred to strings as keys for dictionaries, in particular for instances of `IdentityDictionary`. See also Chapter: Basic Classes for more about `String` and `Symbol`.

## 11.5 Collection iterators

In Pharo loops and conditionals are simply messages sent to collections or other objects such as integers or blocks (see also Chapter: Syntax in a Nutshell). In addition to low-level messages such as `to:do:` which evaluates a block with an argument ranging from an initial to a final number, the collection hierarchy offers various high-level iterators. Using such iterators will make your code more robust and compact.

### Iterating (do:)

The method `do:` is the basic collection iterator. It applies its argument (a block taking a single argument) to each element of the receiver. The following example prints all the strings contained in the receiver to the transcript.

```text
#('bob' 'joe' 'toto') do: [:each | Transcript show: each; cr].
```

**Variants.** There are a lot of variants of `do:`, such as `do:without:`, `doWithIndex:` and `reverseDo:`.

For the indexed collections (`Array`, `OrderedCollection`, `SortedCollection`) the message `doWithIndex:` also gives access to the current index. This message is related to `to:do:` which is defined in class `Number`.

```python
#('bob' 'joe' 'toto')
doWithIndex: [ :each :i | (each = 'joe') ifTrue: [ ^ i ] ]
>>> 2
```

For ordered collections, the message `reverseDo:` walks the collection in the reverse order.

The following code shows an interesting message: `do:separatedBy:` which executes the second block only in between two elements.
```groovy
| res |
res := ''.
#('bob' 'joe' 'toto')
do: [ :e | res := res, e ]
separatedBy: [ res := res, '.' ].
res
>>> 'bob.joe.toto'
```

Note that this code is not especially efficient since it creates intermediate strings and it would be better to use a write stream to buffer the result (see Chapter : Streams):

```groovy
String streamContents: [ :stream |
    #('bob' 'joe' 'toto') asStringOn: stream delimiter: '.' ]
>>> 'bob.joe.toto'
```

## Dictionaries

When the message `do:` is sent to a dictionary, the elements taken into account are the values, not the associations. The proper messages to use are `keysDo:`, `valuesDo:`, and `associationsDo:`, which iterate respectively on keys, values or associations.

```groovy
colors := Dictionary newFrom: { #yellow -> Color yellow. #blue -> Color blue. #red -> Color red }.
colors keysDo: [ :key | Transcript show: key; cr ].
colors valuesDo: [ :value | Transcript show: value; cr ].
colors associationsDo: [:value | Transcript show: value; cr].
```

## Collecting results (`collect:`)

If you want to apply a function to the elements of a collection and get a new collection with the results, rather than using `do:`, you are probably better off using `collect:`, or one of the other iterator methods. Most of these can be found in the enumerating protocol of `Collection` and its subclasses.

Imagine that we want a collection containing the doubles of the elements in another collection. Using the method `do:` we must write the following:

```groovy
| double |
double := OrderedCollection new.
#(1 2 3 4 5 6) do: [ :e | double add: 2 * e ].
double
>>> an OrderedCollection(2 4 6 8 10 12)
```

The message `collect:` executes its argument block for each element and returns a new collection containing the results. Using `collect:` instead, the code is much simpler:
```groovy
[ 
  #(1 2 3 4 5 6) collect: [ :e | 2 * e ]
  >>> #(2 4 6 8 10 12)
]
```

The advantages of collect: over do: are even more important in the following example, where we take a collection of integers and generate as a result a collection of absolute values of these integers:

```groovy
[
  aCol := #(
    2 - 3   4 - 35   4 - 11
  ).
  result := aCol species new: aCol size.
  1 to: aCol size do: [ :each | result at: each put: (aCol at: each) abs
  ].
  result
>>> #(
  2  3   4  35   4  11
)
```

Contrast the above with the much simpler following expression:

```groovy
[
  #(
    2 - 3   4 - 35   4 - 11
  ) collect: [ :each | each abs ]
>>> #(
  2  3   4  35   4  11
)
```

A further advantage of the second solution is that it will also work for sets and bags. Generally you should avoid using do:, unless you want to send messages to each of the elements of a collection.

Note that sending the message collect: returns the same kind of collection as the receiver. For this reason the following code fails. (A String cannot hold integer values.)

```groovy
[ 'abc' collect: [ :ea | ea asciiValue ]
>>> "error!"
```

Instead we must first convert the string to an Array or an OrderedCollection:

```groovy
[ 'abc' asArray collect: [ :ea | ea asciiValue ]
>>> #(
  97  98  99
)
```

Actually collect: is not guaranteed to return a collection of exactly the same class as the receiver, but only the same species. In the case of an Interval, the species is an Array!

```groovy
[
  (1 to: 5) collect: [ :ea | ea * 2 ]
>>> #(
  2  4   6   8  10
)
```

## Selecting and rejecting elements

The message select: returns the elements of the receiver that satisfy a particular condition:

```groovy
[ (2 to: 20) select: [ :each | each isPrime ]
>>> #(
  2  3  5  7  11  13  17  19
)
```

The message reject: does the opposite:
```python
(2 to: 20) reject: [ :each | each isPrime ]
>>> #(4 6 8 9 10 12 14 15 16 18 20)
```

### Identifying an element with detect:

The message `detect:` returns the first element of the receiver that matches block argument.

```python
'through' detect: [ :each | each isVowel ]
>>> $o
```

The message `detect:ifNone:` is a variant of the method `detect:`. Its second block is evaluated when there is no element matching the block.

```python
Smalltalk globals allClasses
detect: [:each | '*cobol*' match: each asString]
ifNone: [ nil ]
>>> nil
```

### Accumulating results with inject:into:

Functional programming languages often provide a higher-order function called `fold` or `reduce` to accumulate a result by applying some binary operator iteratively over all elements of a collection. In Pharo this is done by `Collection>>inject:into:`.

The first argument is an initial value, and the second argument is a two-argument block which is applied to the result this far, and each element in turn.

A trivial application of `inject:into:` is to produce the sum of a collection of numbers. In Pharo we could write this expression to sum the first 100 integers:

```python
(1 to: 100) inject: 0 into: [ :sum :each | sum + each ]
>>> 5050
```

Another example is the following one-argument block which computes factorials:

```python
factorial := [ :n | (1 to: n) inject: 1 into: [ :product :each | product * each ] ].
factorial value: 10
>>> 3628800
```

### Other messages

There are many other iterator messages. Just check the `Collection` class.
11.6 Some hints for using collections

**count:** The message count: returns the number of elements satisfying a condition. The condition is represented as a boolean block.

```
Smalltalk globals allClasses
count: [ :each | 'Collection*' match: each asString ]
>>> 6
```

**includes:** The message includes: checks whether the argument is contained in the collection.

```
| colors |
colors := {Color white . Color yellow . Color blue . Color orange}.
colors includes: Color blue.
>>> true
```

**anySatisfy:** The message anySatisfy: answers true if at least one element of the collection satisfies the condition represented by the argument.

```
colors anySatisfy: [ :c | c red > 0.5 ]
>>> true
```

## 11.6 Some hints for using collections

**A common mistake with add:** The following error is one of the most frequent Smalltalk mistakes.

```
| collection |
collection := OrderedCollection new add: 1; add: 2.
collection
>>> 2
```

Here the variable collection does not hold the newly created collection but rather the last number added. This is because the method add: returns the element added and not the receiver.

The following code yields the expected result:

```
| collection |
collection := OrderedCollection new.
collection add: 1; add: 2.
collection
>>> an OrderedCollection(1 2)
```

You can also use the message yourself to return the receiver of a cascade of messages:

```
| collection |
collection := OrderedCollection new add: 1; add: 2; yourself
>>> an OrderedCollection(1 2)
```
**Removing an element of the collection you are iterating on**
Another mistake you may make is to remove an element from a collection you are currently iterating over.

```groovy
[ 
    range |
    range := (2 to: 20) asOrderedCollection.
    range do: [ :aNumber | aNumber isPrime
                ifFalse: [ range remove: aNumber ] ].
    range
>>> an OrderedCollection(2 3 5 7 9 11 13 15 17 19)
```

This result is clearly incorrect since 9 and 15 should have been filtered out!

The solution is to copy the collection before going over it.

```groovy
[ 
    range |
    range := (2 to: 20) asOrderedCollection.
    range copy do: [ :aNumber | aNumber isPrime
                    ifFalse: [ range remove: aNumber ] ].
    range
>>> an OrderedCollection(2 3 5 7 11 13 17 19)
```

**Redefining = but not hash**
A difficult error to spot is when you redefine = but not hash. The symptoms are that you will lose elements that you put in sets or other strange behaviour. One solution proposed by Kent Beck is to use `bitXor`: to redefine hash. Suppose that we want two books to be considered equal if their titles and authors are the same. Then we would redefine not only = but also hash as follows:

```groovy
Book >> = aBook
        self class = aBook class ifFalse: [ ^ false ].
        ^ title = aBook title and: [ authors = aBook authors ]

Book >> hash
        ^ title hash bitXor: authors hash
```

Another nasty problem arises if you use a mutable object, i.e., an object that can change its hash value over time, as an element of a `Set` or as a key to a `Dictionary`. Don't do this unless you love debugging!

## 11.7 Chapter summary

The collection hierarchy provides a common vocabulary for uniformly manipulating a variety of different kinds of collections.

* A key distinction is between `SequenceableCollections`, which maintain their elements in a given order, `Dictionary` and its subclasses, which maintain key-to-value associations, and `Sets` and `Bags`, which are unordered.
* You can convert most collections to another kind of collection by sending them the messages `asArray`, `asOrderedCollection` etc.

* To sort a collection, send it the message `asSortedCollection`.

* `#( ... )` creates arrays containing only literal objects (i.e., objects created without sending messages). `{ ... }` creates dynamic arrays using a compact form.

* A `Dictionary` compares keys by equality. It is most useful when keys are instances of `String`. An `IdentityDictionary` instead uses object identity to compare keys. It is more suitable when `Symbols` are used as keys, or when mapping object references to values.

* `Strings` also understand the usual collection messages. In addition, a `String` supports a simple form of pattern-matching. For more advanced application, look instead at the `RegEx` package.

* The basic iteration message is `do:`. It is useful for imperative code, such as modifying each element of a collection, or sending each element a message.

* Instead of using `do:`, it is more common to use `collect:`, `select:`, `reject:`, `includes:`, `inject:into:` and other higher-level messages to process collections in a uniform way.

* Never remove an element from a collection you are iterating over. If you must modify it, iterate over a copy instead.

* If you override `=`, remember to override `hash` as well!
<figure><img src="image_110.png" /></figure>
CHAPTER 12

Streams

Streams are used to iterate over sequences of elements such as sequenced
collections, files, and network streams. Streams may be either readable,
or writeable, or both. Reading or writing is always relative to the current
position in the stream. Streams can easily be converted to collections, and vice
versa.

12.1 Two sequences of elements

A good metaphor to understand a stream is the following. A stream can be
represented as two sequences of elements: a past element sequence and a
future element sequence. The stream is positioned between the two sequences.
Understanding this model is important, since all stream operations in Pharo
rely on it. For this reason, most of the Stream classes are subclasses of Posi-
tionableStream. Figure 12.1 presents a stream which contains five characters.
This stream is in its original position, i.e., there is no element in the past. You
can go back to this position using the message reset defined in Position-
ableStream.

Reading an element conceptually means removing the first element of the
future element sequence and putting it after the last element in the past

<figure><img src="image_111.png" /><figcaption>**Figure 12.1:** A stream positioned at its beginning.</figcaption></figure>
<figure><img src="image_112.png" /><figcaption>**Figure 12.2:** The same stream after the execution of the method `next`: the character `a` is in the past whereas `b`, `c`, `d` and `e` are in the future.</figcaption></figure>

<figure><img src="image_113.png" /><figcaption>**Figure 12.3:** The same stream after having written an `x`.</figcaption></figure>

element sequence. After having read one element using the message `next`, the state of your stream is that shown in Figure 12.2.

Writing an element means replacing the first element of the future sequence by the new one and moving it to the past. Figure 12.3 shows the state of the same stream after having written an `x` using the message `nextPut`: an element defined in `Stream`.

## 12.2 Streams vs. collections

The collection protocol supports the storage, removal and enumeration of the elements of a collection, but does not allow these operations to be intermingled. For example, if the elements of an `OrderedCollection` are processed by a `do:` method, it is not possible to add or remove elements from inside the `do:` block. Nor does the collection protocol offer ways to iterate over two collections at the same time, choosing which collection goes forward and which does not. Procedures like these require that a traversal index or position reference is maintained outside of the collection itself: this is exactly the role of `ReadStream`, `WriteStream` and `ReadWriteStream`.

These three classes are defined to *stream over* some collection. For example, the following snippet creates a stream on an interval, then it reads two elements.

```java
| r |
 r := ReadStream on: (1 to: 1000).
 r next.
>>> 1
 r next.
>>> 2
 r atEnd.
>>> false
```
WriteStreams can write data to the collection:

```
| w |
 w := WriteStream on: (String new: 5).
 w nextPut: $a.
 w nextPut: $b.
 w contents.
>>> 'ab'
```

It is also possible to create ReadWriteStreams that support both the reading and writing protocols.

Streams are not only meant for collections, they can be used for files or sockets too. The following example creates a file named test.txt, writes two strings to it, separated by a carriage return, and closes the file.

```
StandardFileStream
    fileNamed: 'test.txt'
do: [:str | str
    nextPutAll: '123';
    cr;
    nextPutAll: 'abcd' ].
```

The following sections present the protocols in more depth.

## 12.3 Streaming over collections

Streams are really useful when dealing with collections of elements, and can be used for reading and writing those elements. We will now explore the stream features for collections.

### Reading collections

Using a stream to read a collection essentially provides you a pointer into the collection. That pointer will move forward on reading, and you can place it wherever you want. The class ReadStream should be used to read elements from collections.

Messages next and next: defined in ReadStream are used to retrieve one or more elements from the collection.

```
| stream |
 stream := ReadStream on: #(1 (a b c) false).
 stream next.
>>> 1
 stream next.
>>> #(#a #b #c)
 stream next.
>>> false
```
```
| stream |
stream := ReadStream on: 'abcdef'.
stream next: 0.
>>> ''
stream next: 1.
>>> 'a'
stream next: 3.
>>> 'bcd'
stream next: 2.
>>> 'ef'
```

The message peek defined in PositionableStream is used when you want to know what is the next element in the stream without going forward.

```
stream := ReadStream on: '-143'.
"look at the first element without consuming it."
negative := (stream peek = $-).
negative.
>>> true
"ignores the minus character"
negative ifTrue: [ stream next ].
number := stream upToEnd.
number.
>>> '143'
```

This code sets the boolean variable `negative` according to the sign of the number in the stream, and `number` to its absolute value. The message `upToEnd` defined in `ReadStream` returns everything from the current position to the end of the stream and sets the stream to its end. This code can be simplified using the message `peekFor`: defined in `PositionableStream`, which moves forward if the following element equals the parameter and doesn't move otherwise.

```
| stream |
stream := '-143' readStream.
(stream peekFor: $-)
>>> true
stream upToEnd
>>> '143'
```

`peekFor` also returns a boolean indicating if the parameter equals the element.

You might have noticed a new way of constructing a stream in the above example: one can simply send the message `readStream` to a sequenceable collection (such as a `String`) to get a reading stream on that particular collection.

## Positioning

There are messages to position the stream pointer. If you have the index, you can go directly to it using `position: defined in PositionableStream`. You
<figure><img src="image_114.png" /><figcaption>**Figure 12.4:** A stream at position 2.</figcaption></figure>

can request the current position using `position`. Please remember that a stream is not positioned on an element, but between two elements. The index corresponding to the beginning of the stream is 0.

You can obtain the state of the stream depicted in 12.4 with the following code:

```perl
stream := 'abcde' readStream.
stream position: 2.
stream peek
>>> $c
```

To position the stream at the beginning or the end, you can use the message `reset` or `setToEnd`. The messages `skip:` and `skipTo:` are used to go forward to a location relative to the current position: `skip:` accepts a number as argument and skips that number of elements whereas `skipTo:` skips all elements in the stream until it finds an element equal to its parameter. Note that it positions the stream after the matched element.

```perl
stream := 'abcdef' readStream.
stream next.
>>> $a "stream is now positioned just after the a"
stream skip: 3. "stream is now after the d"
stream position.
>>> 4
stream skip: -2. "stream is after the b"
stream position.
>>> 2
stream reset.
stream position.
>>> 0
stream skipTo: $e. "stream is just after the e now"
stream next.
>>> $f
stream contents.
>>> 'abcdef'
```

As you can see, the letter e has been skipped.

The message `contents` always returns a copy of the entire stream.
## Testing

Some messages allow you to test the state of the current stream: `atEnd` returns true if and only if no more elements can be read, whereas `isEmpty` returns true if and only if there are no elements at all in the collection.

Here is a possible implementation of an algorithm using `atEnd` that takes two sorted collections as parameters and merges those collections into another sorted collection:

```
| stream1 stream2 result |
stream1 := #(1 4 9 11 12 13) readStream.
stream2 := #(1 2 3 4 5 10 13 14 15) readStream.

"The variable result will contain the sorted collection."
result := OrderedCollection new.
[stream1 atEnd not & stream2 atEnd not ]
whileTrue: [
    stream1 peek < stream2 peek
    "Remove the smallest element from either stream and add it to
     the result."
    ifTrue: [result add: stream1 next ]
    ifFalse: [result add: stream2 next ]].

"One of the two streams might not be at its end. Copy whatever remains."
result
    addAll: stream1 upToEnd;
    addAll: stream2 upToEnd.

result.
>>> an OrderedCollection(1 1 2 3 4 4 5 9 10 11 12 13 13 14 15)
```

## Writing to collections

We have already seen how to read a collection by iterating over its elements using a `ReadStream`. We'll now learn how to create collections using `WriteStreams`.

`WriteStreams` are useful for appending a lot of data to a collection at various locations. They are often used to construct strings that are based on static and dynamic parts, as in this example:

```
| stream |
stream := String new writeStream.
stream
    nextPutAll: 'This Smalltalk image contains: ';
    print: Smalltalk allClasses size;
    nextPutAll: ' classes.';
    cr;
    nextPutAll: 'This is really a lot.'.
```
12.3 Streaming over collections

```groovy
streamContents.
>>> 'This Smalltalk image contains: 2322 classes.
This is really a lot.'
```

This technique is used in the different implementations of the method `printOn()`, for example. There is a simpler and more efficient way of creating strings if you are only interested in the content of the stream:

```groovy
| string |
string := String streamContents:
    [ :stream |
        stream
            print: #(1 2 3);
            space;
            nextPutAll: 'size';
            space;
            nextPut: $=;
            space;
            print: 3. ].
    ]
string.
>>> '(1 2 3) size = 3'
```

The message `streamContents:` defined `SequenceableCollection` creates a collection and a stream on that collection for you. It then executes the block you gave passing the stream as a parameter. When the block ends, `streamContents:` returns the contents of the collection.

The following `WriteStream` methods are especially useful in this context:

* `nextPut`: adds the parameter to the stream;

* `nextPutAll`: adds each element of the collection, passed as a parameter, to the stream;

* `print`: adds the textual representation of the parameter to the stream.

There are also convenient messages for printing useful characters to a stream, such as space, tab and `cr` (carriage return). Another useful method is `ensureASpace` which ensures that the last character in the stream is a space; if the last character isn't a space it adds one.

## About String Concatenation

Using `nextPut:` and `nextPutAll:` on a `WriteStream` is often the best way to concatenate characters. Using the comma concatenation operator (`,` ) is far less efficient:

```groovy
| temp |
temp := String new.
(1 to: 100000)
do: [:i | temp := temp, i asString, ' ' ] ] timeToRun
>>> 115176 "(milliseconds)"
```
<figure><img src="image_115.png" /><figcaption>**Figure 12.5:** A new history is empty. Nothing is displayed in the web browser.</figcaption></figure>

<figure><img src="image_116.png" /><figcaption>**Figure 12.6:** The user opens to page 1.</figcaption></figure>

<figure><img src="image_117.png" /></figure>

The reason that using a stream can be much more efficient is that using a comma creates a new string containing the concatenation of the receiver and the argument, so it must copy both of them. When you repeatedly concatenate onto the same receiver, it gets longer and longer each time, so that the number of characters that must be copied goes up exponentially. This also creates a lot of garbage, which must be collected. Using a stream instead of string concatenation is a well-known optimization.

In fact, you can use the message `streamContents:` defined in `Sequence-ableCollection` class (mentioned earlier) to help you do this:

<figure><img src="image_118.png" /></figure>

Reading and writing at the same time

It's possible to use a stream to access a collection for reading and writing at the same time. Imagine you want to create a `History` class which will manage backward and forward buttons in a web browser. A history would react as in figures 12.5 to 12.11.

This behaviour can be implemented using a `ReadWriteStream`.

<figure><img src="image_119.png" /></figure>
<figure><img src="image_120.png" /><figcaption>**Figure 12.7:** The user clicks on a link to page 2.</figcaption></figure>

<figure><img src="image_121.png" /><figcaption>**Figure 12.8:** The user clicks on a link to page 3.</figcaption></figure>

<figure><img src="image_122.png" /><figcaption>**Figure 12.9:** The user clicks on the Back button. They are now viewing page 2 again.</figcaption></figure>

<figure><img src="image_123.png" /><figcaption>**Figure 12.10:** The user clicks again the back button. Page 1 is now displayed.</figcaption></figure>

<figure><img src="image_124.png" /><figcaption>**Figure 12.11:** From page 1, the user clicks on a link to page 4. The history forgets pages 2 and 3.</figcaption></figure>
```kotlin
classVariableNames: ''
package: 'PBE-Streams'

History >> initialize
super initialize.
stream := ReadWriteStream on: Array new.
```

Nothing really difficult here, we define a new class which contains a stream. The stream is created during the initialize method.

We need methods to go backward and forward:

```kotlin
History >> goBackward
self canGoBackward
ifFalse: [ self error: 'Already on the first element' ].
stream skip: -2.
^ stream next.

History >> goForward
self canGoForward
ifFalse: [ self error: 'Already on the last element' ].
^ stream next
```

Up to this point, the code is pretty straightforward. Next, we have to deal with the goTo: method which should be activated when the user clicks on a link. A possible implementation is:

```kotlin
History >> goTo: aPage
stream nextPut: aPage.
```

This version is incomplete however. This is because when the user clicks on the link, there should be no more future pages to go to, i.e., the forward button must be deactivated. To do this, the simplest solution is to write `nil` just after, to indicate that history is at the end:

```kotlin
History >> goTo: anObject
stream nextPut: anObject.
stream nextPut: nil.
stream back.
```

Now, only methods canGoBackward and canGoForward remain to be implemented.

A stream is always positioned between two elements. To go backward, there must be two pages before the current position: one page is the current page, and the other one is the page we want to go to.

```kotlin
History >> canGoBackward
^ stream position > 1

History >> canGoForward
^ stream atEnd not and: [stream peek notNil ]
```
Let us add a method to peek at the contents of the stream:

```
History >> contents
^ stream contents
```

And the history works as advertised:

```
History new
  goTo: #page1;
  goTo: #page2;
  goTo: #page3;
  goBackward;
  goBackward;
  goTo: #page4;
  contents
>>> #(#page1 #page4 nil nil)
```

## 12.4 Using streams for file access

You have already seen how to stream over collections of elements. It's also possible to stream over files on your hard disk. Once created, a stream on a file is really like a stream on a collection; you will be able to use the same protocol to read, write or position the stream. The main difference appears in the creation of the stream. There are several different ways to create file streams, as we shall now see.

### Creating file streams

To create file streams, you will have to use one of the following instance creation messages offered by the class `FileStream`:

**fileNamed:** Open a file with the given name for reading and writing. If the file already exists, its prior contents may be modified or replaced, but the file will not be truncated on close. If the name has no directory part, then the file will be created in the default directory.

**newFileNamed:** Create a new file with the given name, and answer a stream opened for writing on that file. If the file already exists, ask the user what to do.

**forceNewFileNamed:** Create a new file with the given name, and answer a stream opened for writing on that file. If the file already exists, delete it without asking before creating the new file.

**oldFileNamed:** Open an existing file with the given name for reading and writing. If the file already exists, its prior contents may be modified or replaced, but the file will not be truncated on close. If the name has no directory part, then the file will be created in the default directory.

**readOnlyFileNamed:** Open an existing file with the given name for reading.
You have to remember that each time you open a stream on a file, you have to close it too. This is done through the `=close` message defined in `FinancialStream`.

```json
{
    "stream":
        {
            "stream":
                {
                    "nextPutAll": 'This text is written in a file named ';
                    "print": "stream localName.
                }
            "stream close.
        }
        {
            "stream":
                {
                    "readOnlyFileNamed": 'test.txt'.
                }
            "stream contents.
        }
        {
            "stream close.
        }
```

The message `localName` defined in class `FinancialStream` answers the last component of the name of the file. You can also access the full path name using the message `fullname`.

You will soon notice that manually closing the file stream is painful and error-prone. That's why `FinancialStream` offers a message called `forceNewFileNamed:do:` to automatically close a new stream after evaluating a block that sets its contents.

```json
{
    "string":
        {
            "forceNewFileNamed": 'test.txt'
        }
    "do": [
        "stream"{
            "nextPutAll": 'This text is written in a file named ';
            "print": "stream localName ".
        }
        "string"{
            "readOnlyFileNamed": 'test.txt'
        }
        "do": [
            "stream"{
                "readOnlyFileNamed": 'test.txt'
            }
        ]
    }
    "string"
}
```

The stream creation methods that take a block as an argument first create a stream on a file, then execute the block with the stream as an argument, and finally close the stream. These methods return what is returned by the block, which is to say, the value of the last expression in the block. This is used in the previous example to get the content of the file and put it in the variable `string`.

## Binary streams

By default, created streams are text-based which means you will read and write characters. If your stream must be binary, you have to send the message `binary` to your stream.
When your stream is in binary mode, you can only write numbers from 0 to
255 (1 Byte). If you want to use `nextPutAll`: to write more than one number
at a time, you have to pass a `byteArray` as argument.

```java
[ 
    Satellite
        forceNewFileNamed: 'test.bin'
        do: [ :stream |
                stream
                binary;
                nextPutAll: #(145 250 139 98) asByteArray ].
]
[ 
    Satellite
        Premade
            PremadeFileNamed: 'test.bin'
            do: [ :stream |
                    stream binary.
                    stream size.
                >>> 4
                    stream next.
                >>> 145
                    stream upToEnd.
                >>> #[250 139 98 ]
            ].
]
```

Here is another example which creates a picture in a file named `test.pgm`
(portable graymap file format). You can open this file with your favorite
drawing program.

```java
[ 
    Satellite
        forceNewFileNamed: 'test.pgm'
        do: [ :stream |
                stream
                    nextPutAll: 'P5'; cr;
                    nextPutAll: '4 4'; cr;
                    nextPutAll: '255'; cr;
                binary;
                    nextPutAll: #(255 0 255 0) asByteArray;
                    nextPutAll: #(0 255 0 255) asByteArray;
                    nextPutAll: #(255 0 255 0) asByteArray;
                    nextPutAll: #(0 255 0 255) asByteArray ]
]
```

This creates a 4x4 checkerboard as shown in 12.12.

## 12.5 Chapter summary

Streams offer a better way (compared to collections) to incrementally read and write a sequence of elements. There are easy ways to convert back and forth between streams and collections.

* Streams may be either readable, writeable or both readable and writeable.
<figure><img src="image_125.png" /><figcaption>**Figure 12.12:** A 4x4 checkerboard you can draw using binary streams.</figcaption></figure>

* To convert a collection to a stream, define a stream on a collection, e.g., `ReadStream on: (1 to: 1000)`, or send the messages `readStream`, etc. to the collection.

* To convert a stream to a collection, send the message `contents`.

* To concatenate large collections, instead of using the comma operator, it is more efficient to create a stream, append the collections to the stream with `nextPutAll:`, and extract the result by sending `contents`.

* File streams are by default character-based. Send `binary` to explicitly make them binary.
CHAPTER 13

Morphic

Morphic is the name given to Pharo's graphical interface. Morphic is written in Pharo, so it is fully portable between operating systems. As a consequence, Pharo looks exactly the same on Unix, MacOS and Windows. What distinguishes Morphic from most other user interface toolkits is that it does not have separate modes for *composing* and *running* the interface: all the graphical elements can be assembled and disassembled by the user, at any time. (We thank Hilaire Fernandes for permission to base this chapter on his original article in French.)

13.1 The history of Morphic

Morphic was developed by John Maloney and Randy Smith for the Self programming language, starting around 1993. Maloney later wrote a new version of Morphic for Squeak, but the basic ideas behind the Self version are still alive and well in Pharo Morphic: *directness* and *liveness*. Directness means that the shapes on the screen are objects that can be examined or changed directly, that is, by clicking on them using a mouse. Liveness means that the user interface is always able to respond to user actions: information on the screen is continuously updated as the world that it describes changes. A simple example of this is that you can detach a menu item and keep it as a button.

Bring up the World Menu and meta-click once on it to bring up its morphic halo, then meta-click again on a menu item you want to detach, to bring up that item's halo. (Recall that you should set halosEnabled in the Preferences browser.) Now drag that item elsewhere on the screen by grabbing the black handle (see Figure 13.1), as shown in Figure 13.2.
<figure><img src="image_126.png" /><figcaption>**Figure 13.1:** The grab handle.</figcaption></figure>

<figure><img src="image_127.png" /><figcaption>**Figure 13.2:** Detaching a morph, here the Playground menu item, to make it an independent button.</figcaption></figure>

All of the objects that you see on the screen when you run Pharo are *Morphs*, that is, they are instances of subclasses of class *Morph*. *Morph* itself is a large class with many methods; this makes it possible for subclasses to implement interesting behaviour with little code. You can create a *morph* to represent any object, although how good a representation you get depends on the object!

To create a *morph* to represent a string object, execute the following code in a *Playground*.

```Flash
['Morph' asMorph openInWorld
```

This creates a *Morph* to represent the string 'Morph', and then opens it (that is, displays it) in the *world*, which is the name that Pharo gives to the screen. You should obtain a graphical element (a *Morph*), which you can manipulate by meta-clicking.

Of course, it is possible to define *morphs* that are more interesting graphical representations than the one that you have just seen. The method *asMorph* has a default implementation in class *Object* class that just creates a *String-Morph*. So, for example, *Color* *tan* *asMorph* returns a *StringMorph* labeled with the result of *Color* *tan* *printString*. Let's change this so that we get a coloured rectangle instead.

Open a browser on the *Color* class and add the following method to it:

```Flash
Color >> asMorph
^ Morph new color: self
```

Now execute *Color* *orange* *asMorph* *openInWorld* in a *Playground*. Instead of the string-like *morph*, you get an orange rectangle (see Figure 13.3)!
<figure><img src="image_128.png" /><figcaption>**Figure 13.3:** Color orange asMorph openInWorld with our new method.</figcaption></figure>

## 13.2 Manipulating morphs

Morphs are objects, so we can manipulate them like any other object in Pharo: by sending messages, we can change their properties, create new subclasses of Morph, and so on.

Every morph, even if it is not currently open on the screen, has a position and a size. For convenience, all morphs are considered to occupy a rectangular region of the screen; if they are irregularly shaped, their position and size are those of the smallest rectangular box that surrounds them, which is known as the morph's bounding box, or just its *bounds*. The *position* method returns a *Point* that describes the location of the morph's upper left corner (or the upper left corner of its bounding box). The origin of the coordinate system is the screen's upper left corner, with y coordinates increasing *down* the screen and x coordinates increasing to the right. The *extent* method also returns a *point*, but this *point* specifies the width and height of the morph rather than a location.

Type the following code into a playground and Do it:

```ruby
joe := Morph new color: Color blue.
joe openInWorld.
bill := Morph new color: Color red.
bill openInWorld.
```

Then type `joe position` and then `Print it`. To move joe, execute `joe position: (joe position + (10@3))` repeatedly (see Figure 13.4).

It is possible to do a similar thing with size. `joe extent` answers joe's size; to have joe grow, execute `joe extent: (joe extent * 1.1)`. To change the color of a morph, send it the `color:` message with the desired Color object as
<figure><img src="image_129.png" /><figcaption>**Figure 13.4:** Bill and Joe after 10 moves.</figcaption></figure>

argument, for instance, `joe color: Color orange`. To add transparency, try `joe color: (Color orange alpha: 0.5)`.

To make bill follow joe, you can repeatedly execute this code:

```
[ bill position: (joe position + (100@0))
```

If you move joe using the mouse and then execute this code, bill will move so that it is 100 pixels to the right of joe.

You can see the result on Figure 13.5

## 13.3 Composing morphs

One way of creating new graphical representations is by placing one morph inside another. This is called *composition*; morphs can be composed to any depth.

You can place a morph inside another by sending the message `addMorph` to the container morph.

Try adding a morph to another one:

```
[ balloon := BalloonMorph new color: Color yellow.
    joe addMorph: balloon.
```
<figure><img src="image_130.png" /><figcaption>**Figure 13.5:** Bill follows Joe.</figcaption></figure>

<figure><img src="image_131.png" /><figcaption>**Figure 13.6:** The balloon is contained inside joe, the translucent orange morph.</figcaption></figure>

balloon position: joe position.

The last line positions the balloon at the same coordinates as joe. Notice that the coordinates of the contained morph are still relative to the screen, not to the containing morph. There are many methods available to position a morph; browse the geometry protocol of class Morph to see for yourself. For example, to center the balloon inside joe, execute `balloon center: joe center`.

If you now try to grab the balloon with the mouse, you will find that you actually grab joe, and the two morphs move together: the balloon is *embedded* inside joe. It is possible to embed more morphs inside joe. In addition to doing this programmatically, you can also embed morphs by direct manipulation.