<figure><img src="image_1.png" /></figure>

HAL
open science

Smalltalk by Example

Alec Sharp

► To cite this version:

Alec Sharp. Smalltalk by Example. 1997. hal-05171672

HAL Id: hal-05171672

https://hal.science/hal-05171672v1

Submitted on 20 Jul 2025

HAL is a multi-disciplinary open access
archive for the deposit and dissemination of sci-
entific research documents, whether they are pub-
lished or not. The documents may come from
teaching and research institutions in France or
abroad, or from public or private research centers.

L'archive ouverte pluridisciplinaire HAL, est
destinée au dépôt et à la diffusion de documents
scientifiques de niveau recherche, publiés ou non,
émanant des établissements d'enseignement et de
recherche français ou étrangers, des laboratoires
publics ou privés.

Public Domain
Smalltalk
THE DEVELOPER'S GUIDE

by

Example

Featuring
VisualWorks

A L E C
S H A R P

Copyright © 1997 by Alec Sharp
PDF-Conversion by Lukas Renggli

Download more free Smalltalk-Books at:
The University of Berne: http://www.iam.unibe.ch/~ducasse/WebPages/FreeBooks.html
European Smalltalk Users Group: http://www.esug.org
This book has been prepared by Lukas Renggli and Stéphane Ducasse.

We thank the author that gave us the right to make this great book available to everybody.

Bern 30th of Augut 2004

If you want to help promoting smalltalk contact ESUG: www.esug.org
Acknowledgments

I'd like to thank all those people who helped during the development of this manuscript, by reviewing parts of the manuscript, by general feedback, or by other assistance. Those people include TW Cook, Jim Dutton, and Boyd Hays of ParcPlace-Digitalk, Dave Farmer, Clark Hobbie, Mike Latta, Dave Muirhead, Dave Myers, and Bill Wright. I also received valuable contributions from those anonymous reviewers of an early draft whose favorable opinions were vital to getting this manuscript published. To all of these people: your comments and suggestions have helped make this book considerably better than it might have been. To the anonymous reviewers: thanks for the favorable opinions!

Thanks also all the people I worked with at McGraw-Hill who helped bring this book from concept to reality.
In particular, Scott Amerman, Michael Christopher, Jennifer DiGiovanna, and John Wyzalek.

I also want to thank all those people who have contributed to whatever knowledge I have of object-oriented thinking and Smalltalk programming. Many people have contributed to my education, including the authors of various books and magazine articles. From this group I'd like to acknowledge Kent Beck and Alan Knight for their wonderful articles in The Smalltalk Report. Of the people I have worked with, I'd like to particularly thank the following: Rob Forbes, Boyd Hays, Clark Hobbie, Mike Latta, Alan Wostenberg, Bill Wright, and the Daves (Bond, Farmer, Muirhead, and Myers).

In particular, I'd like to thank four friends for special contributions. Dave Farmer for all the fun we had learning Smalltalk and working on our first Smalltalk project together. Boyd Hays for the philosophy and information he imparted when he came in as a consultant to review the design and progress of our first project. Scott Allen, my manager at StorageTek, who had the courage to bring in Smalltalk and commit to doing a key project in it. Bill Wright for the incredible review he did of the final manuscript, and for being the greatest office partner. To these four people: thanks.

Most of all, I want to acknowledge and thank the people whose lives were most affected by this book: my daughter, Nikki, who had less of a father during the evenings and weekends I worked on the book, and my wife, Muriel, to whom I offer the greatest thanks. On top of her own busy life she took on many additional household and child-minding duties as I spent long hours at the computer. Thanks, I couldn't have done it without you.
# Introduction

This book is the book that I wanted when I started programming in Smalltalk. None of the books on the market seemed quite right; they all lacked some of what I needed to get my job done. Some were more like reference books, making sense if one already understood the material, but not very good if one lacked the basic knowledge. Others simply went over material that I could easily get by looking at the system classes using a Browser. The bottom line was that none of them seemed to provide answers to the questions I had: how do I use these capabilities when writing my application, how can I do the specific things I want to do, which is the best approach to take, how can I modify my development environment to make it more productive? In short, I wanted information that would steer me in the right direction and none of the books seemed to give that. This book is written for people who have similar questions and needs, who want to become productive in Smalltalk programming in as short a time as possible.

A lot of the material describes standard Smalltalk, but some material is specific to VisualWorks from ParcPlace-Digitalk. The book assumes that the reader is using VisualWorks 2.0 or VisualWorks 2.5, and where appropriate it explains the differences between these two releases. All the examples have been verified on both VisualWorks 2.0 and VisualWorks 2.5. Note that in most examples, to save space I have not shown the temporary variable declarations, so you will be prompted when you try to run or accept the code.

## Approach

"Example is the school of mankind, and they will learn at no other". Like Edmund Burke, and like most people, I learn best from example. People generally find it difficult to take a theory and apply it to create a practical example. They usually find it far easier to take a concrete example, work with it, and extrapolate out the general behavior. Because of this, I've tried to include plenty of examples in the book, practical examples that the reader can use when developing applications. My goal has been to make this book different by focusing on practicality, on helping developers solve the real programming problems they face. The book has an attached diskette which contains the code for most of the examples.

This book presents the information that the reader needs in order to understand the concepts and the capabilities of Smalltalk. It then goes a step beyond and gives practical examples of how readers would use the capabilities when developing products. The book starts with the basic concepts of object-oriented development, specifically in the context of Smalltalk programming. It builds on this and talks about control structures, Collections, Streams, and other useful building blocks. Then it extends the basics and shows how the reader can use the Smalltalk classes when writing application programs. For example, Chapter 20, Error Handling, looks at the Signal and Exception mechanism that Smalltalk provides, then shows how you might use this mechanism when writing your application. Chapter 30, Testing, shows how you might test your application. Chapter 33,

Copyright © 1997 by Alec Sharp

Download more free Smalltalk-Books at:

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

- European Smalltalk Users Group: http://www.esug.org
Managing Source Code, shows how you can track your changes, make sure that your image has the latest
changes, and build a production image from the latest changes.

Layout of the book

The book is split into five sections: Basics, the Basic System Classes, Skills and Techniques, User Interface, and Advanced.

Section One, Basics, talks about the basics of Smalltalk. It talks about *objects* and *classes*, about *messages* and *methods*, and about variables and language syntax. It covers creating instances of classes and controlling program flow with the various conditional and looping structures. It ends with a chapter on thinking in terms of objects.

Section Two, the Basic System Classes, goes over some of the fundamental classes that you will use. Because everything in Smalltalk is an object, and all objects are instances of a class, we will talk about classes in every section. However, Section Two is more information oriented and less technique oriented than some of the other sections.

Section Three, Skills and Techniques, also talks a lot about the system classes, but covers techniques in using the classes. It shows how you work with Processes, how you can implement error handling code, and how to debug in Smalltalk. The section covers a lot of skills and techniques that you will use when developing your application.

Section Four, User Interface, focuses on user interface issues. It gives a lot of attention to the Model-View-
Controller paradigm, then talks about how you can modify user interfaces at run-time. Since the user interface
mechanisms differs widely between the different flavors of Smalltalk, this is the section most specific to
VisualWorks.

Section Five, Advanced, is an advanced section, not because the topics are esoteric, but because the chapters tend to use advanced techniques or knowledge. In fact, some of the material in this section may be very useful, covering such topics as testing, adding methods to system classes, and customizing your development environment.

The book includes a comprehensive index. I've always been frustrated when I know a book contains the information I want, but I can't find it. So I hope this index proves to be less frustrating than some. However, some chapters, such as those on Collections, Streams, Object, and Meta-Programming, make passing references to a lot of messages, and I will not duplicate those references in the index.

Examples

The book contains many examples of Smalltalk code to illustrate points made in the chapters. There are two flavors of code: code that you can type into a workspace, highlight, and evaluate or inspect; and code that consists of classes and methods. The accompanying diskette contains all the code shown in the book. The two types of code are separated into two types of file. Files with an extension of .ex contain example code to be selected and evaluated. Files with an extension of .st contain classes and methods that can be filed into the image. Appendix A, Source Files, describes which files relate to which chapters.
(When highlighting and selecting code in a Workspace, you will sometimes find that when you click to the right of the code, the following line is highlighted rather than the line to the left of where you click. By ending the statement with a period you can prevent this problem.)

## Target audience

Based on a categorization of Smalltalk programmers into three categories — beginner, intermediate, and expert — this book is targeted at beginning to intermediate Smalltalk programmers. Expert programmers may get some useful new information from the book, but they will also know a great deal of what it contains. Beginning and intermediate programmers should find that the book answers a lot of questions about how to program in Smalltalk, how to use the system classes, and how to incorporate the Smalltalk mechanisms into application programs. It is a beginner book in the sense that it goes over the basic concepts, talking about classes, instances, messages and methods, then building on this to look at Collections, Streams, Processes, and so on. However, it doesn't spend as long on the basics as would a book geared totally toward beginners. My feeling is that it doesn't take too long to understand the basics, and I wanted this book to have greater use than just a few weeks. It is an intermediate book in that it gives suggestions on how the reader might write better applications, eliminate procedural code, implement more effective error handling mechanisms, and better test their software. It also contains many tips and hints that often take years to discover.

The book expects some amount of programming experience, whether in procedural or object-oriented programming. A complete novice will get some use from the book, but it will take more effort. While no significant knowledge of object-oriented programming or of Smalltalk is required, I do assume some basic knowledge of the VisualWorks tools, including how to use the Browsers to define classes and write code (when the book refers to a tool, it is referring to the VisualWorks functionality).

## About Smalltalk

Smalltalk has been around a long time. It's origins date back to the early Seventies, when Alan Kay, then at Xerox PARC, wanted to create a language that children could program in. Kay's classic article, *The Early History of Smalltalk*, published in the ACM SIGPLAN Notices, Volume 28, No. 3, March 1993, talks about the evolution of early Smalltalk and about the influences of other languages on it.

Smalltalk was the original Object-Oriented (OO) language, and is still among the purest of OO languages. Unlike hybrid languages such as C++, Smalltalk forces you to think and program in OO terms. When it was originally developed it ran on its own hardware, and was basically the operating system for the hardware. Perhaps due to that heritage, it contains a lot of useful process control features that one would normally associate with an operating system, such as forked processes, semaphores, and mutual exclusion semaphores.

For most of its life, Smalltalk was associated with research and prototyping. However, it is now the fastest growing OO language. The advent of C++ has popularized and legitimized OO programming, but over time some people have become frustrated with the difficulties inherent in C++ development. Because of the new legitimacy of OO development and the difficulties of C++ development, a lot of attention has turned to Smalltalk. It has been further legitimized by IBM, which has made Smalltalk an important part of their development language strategy.
Smalltalk is often used for business applications, but it is also used for applications with a greater engineering orientation. Texas Instruments used Smalltalk to control an entire state-of-the-art wafer fabrication plant, adding extensions to allow distributed objects. Hewlett-Packard created Distributed Smalltalk, an extension to ParcPlace's VisualWorks that allows objects to communicate transparently over networks. Back in the Eighties, Tektronix began to use Smalltalk to run their logic analyzers and datascopes.

## Features of Smalltalk

Smalltalk is a wonderful language to work with — in fact, it's hard to imagine a serious programming language being more fun than Smalltalk. Certainly, I've had more fun programming in Smalltalk than any other language I've worked with; so much fun that at times it's seemed incredible that I've also been paid to enjoy myself. If Smalltalk is so great, what makes it this way? I think it's a combination of things. In no particular order, here are some of those things.

### Interpreted language

Smalltalk is conceptually an interpreted language. This means you can make changes to code and immediately execute them without having to go through a lengthy compile and link process. In fact, you can make code changes to an application that is actually running and have the changes take effect next time that piece of code is executed. You can also write short code segments (in any window) and execute them immediately<fnref n="1" />.

### Browsers

Smalltalk is a very well thought out environment, with a rich set of browsing tools. Because it was designed with children in mind, it is very easy to use. You can look at classes and their methods, and you can see just the local methods or also include inherited methods. From within a method you can ask to see all the methods that invoke it (the senders of the message), all the implementors of identically named methods (polymorphism), or you can browse the code of any of the methods this method invokes. From any of these displays you can modify code.

### The Debugger

The debugger gives you a stack trace of where you are, allowing you to look at any of the methods in the stack and to inspect any of the variables. The inspection capability is excellent, allowing you to easily follow through objects and their own instance variables using just the mouse. As well as inspecting object values, you can also change them. The debugger also has the browsing capabilities of being able to look at senders and implementors of methods. Because of the interpreted nature of Smalltalk, you can evaluate code segments in the

<footnote n="1">¹ While Smalltalk is conceptually interpreted, the actual implementation is rather more sophisticated. When you *accept* a method, the compiler checks it for correctness, complains about syntax errors, gives you warnings about semantic errors, then compiles your text into byte codes. Having pre-compiled byte codes to interpret at run time is a lot faster than interpreting the text each time. On top of that, VisualWorks caches the machine instructions. When the byte code are interpreted, machine instructions are generated and executed. VisualWorks caches the machine instructions so that it doesn't need to interpret the byte codes next time it executes the method. Of course, as in any cache, infrequently used methods may be swapped out.</footnote>
debugger and also change the methods that are stopped in. Being able to change a method then continue
execution is one of the best features of the debugger. In fact, I often consciously program using the debugger. If I
don't know exactly how to program a method, I'll simply ask the method to bring up a debugger by writing `self.halt`. Then I'll write the method in the debugger, using it to inspect variables and evaluate code snippets as I
write.

## The Class Library

One of the big productivity gains comes from reusable software. Smalltalk provides a class library of around one thousand classes, all of which make life a lot easier and a lot more productive for programmers. (In a new VisualWorks 2.5 image with no additional tools or classes loaded, there are 960 classes and 23,131 methods. With the Advanced Tools loaded, the counts are 1,014 and 24,529). It's nice to be able to use an already existing class to manage a queue. It's nice to be able to convert it to a sorted collection with a single message send. Most of the classes are conceptually simple — they have a well defined role and perform it well — which allows you to easily combine and reuse objects.

The system class code is all there for you to peruse, which gives you three benefits. First, you can figure out exactly how to use it instead of having to rely on usually incomplete or hard-to-understand documentation. Second, you can learn new techniques from reading the system classes. Third, it makes it a lot easier to subclass from the system classes. For example, some applications using forked processes may find that a simple SharedQueue will suffice for passing objects between processes. Other applications may need a priority based shared queue, and having a visible class library makes this very easy.

The bottom line is that having an extensive class library means that you have a huge amount of high quality code available, which means you can put together applications very quickly.

## The Garbage Collector

One of the features of Smalltalk that makes writing code much easier is the Garbage Collector. When objects are no longer needed, you don't have to explicitly destroy them as in most other object-oriented languages. Instead, they are automatically garbage collected when they are no longer referenced by another object. This garbage collection makes it possible to concentrate on the application problem, not worrying about what will happen to your objects. When they are no longer needed they will simply disappear and the memory will be reclaimed.

## Object-Oriented Thinking

Smalltalk is one of the pure OO languages. Unlike C++, in which it's easy to write procedural code, Smalltalk makes it difficult to write procedural code. It usually takes about 8-12 months for experienced procedural programmers to become fairly automatic in their Object-Oriented (OO) thinking. To use a language that doesn't help that process makes it much easier to remain in a half-way schizophrenic state.

OO thinking is fun and it is different. One difference is that OO development tends to be more iterative than procedural development, more spiral. In OO development we acknowledge that we don't fully understand our objects and their interactions and we acknowledge that they will be changed and transformed as we increasingly understand the problem.
For several reasons, Smalltalk makes it very easy to progress through the spiral of iterative development. We've talked about how easy it is to write, test, and change code. This ease of writing makes it possible to put off real work until later, so a lot of methods will do nothing but ask themselves, or another object, to do something else. This allows you to think in conceptual terms rather than worrying about the details. Smalltalk is wonderful to work with because it helps enforce OO thinking and because it makes it very easy to do iterative, spiral development.

## Modifying and Extending the Environment

One of the great things about Smalltalk is that if you don't like something, you can change it. If you think it should be possible to convert characters to strings by sending them the message `asString`, you can extend Smalltalk to add the new method to the `Character` class (for example, `^String with: self`). If you'd like different menu options available from your `Launcher` window or you'd like different keyboard mappings, it's easy to change the code. We'll see some examples of this in Chapter 31, Customizing your Environment.

## Smalltalk is reflective

The Smalltalk system can reflect on itself — it can look at itself. Because all the system code is available, you can use the system classes to examine how the system classes work. You can write methods that use knowledge of how methods work. Because you have the ability to find out about the nature of classes and objects, you can write code that makes use of this information. Not all applications need this knowledge, but sometimes knowing how classes and objects are put together can help you create a better solution.

## Summary

In the end, no amount of intellectual discussion can really give you a feeling for the power and beauty of Smalltalk. Feelings have to be experienced, not rationalized. So, with this book in hand, get programming!
1

**Basic Concepts**

In traditional programming, we start with a problem to solve. We figure out how to break the problem into smaller parts, then each part into smaller parts still. At each stage we think about how to *do* things. To do something means first doing one thing, then another, then yet another. So, we divide and conquer with an emphasis on *doing*.

In the object-oriented approach, we again start with a problem to solve. We then try to figure out what objects the system has, what their responsibility is, and how they interact. We still divide and conquer, but the emphasis is now on objects and their interactions.

**Objects**

What is an object? In the real world, we can think of objects as *things*: an apple, a car, a person, a house. In the world of programming, we have objects that model real world objects, and we also have objects that exist to make our life easier, such as an input field, a text string, a collection, a number, a file, a window, or a process. The main qualifications for an object are that it can be named and that it is distinguishable from other types of objects. Let's look at the example of a stock that is traded on a Stock Exchange.

What are the properties of an object? An object usually has some data, and it usually has some behavior — it can do things. Our stock object has some data: it holds the name of the stock, its symbol, the current trading price, the number of shares traded in the most recent trade, and the total number of shares traded today. It also has behavior: it can tell you the most recent trading price and it can accumulate the total of shares traded.

A Stock Exchange application will have many, many stock objects, one for each symbol traded on the exchange. It will interact with the stock objects by sending them *messages*. For example, if it wants to know the current price of a stock, let's say the XYX stock, it would send the *price* message to the XYZ stock object. In response, the stock object looks in its data and returns the current price.

If the Stock Exchange gets information across the wire about a trade involving XYZ stock, it sends the message *traded*: *aCount* *price*: *aPrice* to the XYZ stock object (we'll talk a lot more about messages in Chapter 2, Messages). When the stock object receives the message, it will update its data — in this case it will
update the current price, the number of shares most recently traded, and the total traded for the day. *An object consists of its data plus the messages it understands.*

Our stock object consists of the data: `stockName`, `symbol`, current price, most recent trade volume, and trade volume for the day, and the messages: `stockName`, `symbol`, `price`, `lastTraded`, `totalTraded`, and `traded:price:` (plus a few more). The data is stored in *instance variables*. Each stock object has its own copies of the instance variables, so it can store different values for price, symbol, etc.

## Encapsulation

When you send the message `traded: aNumberOfShares price: aPrice` to a particular stock object, it updates its instance variables `price`, `lastTraded`, and `totalTraded`. There is *no* other way to change these variables<fnref n="1" />. No other object can see or modify our XYZ stock object's data except by sending messages. Some messages will cause the stock object to update its data, and some messages will cause it to return the values. But no other object can access the data directly. The data is *encapsulated* in the object Figure 1-1 shows a representation of this encapsulation.

<figure><img src="image_2.png" /><figcaption>**Figure 1-1.** Encapsulation.</figcaption></figure>

The fact that the data is encapsulated means that we can change the way that it is stored. As long as we retain the public interface that we have defined — the messages to which the object responds, we can do what we like internally. One day we might decide to store the price in dollars and cents, the next day in cents, the next day in eighths of a dollar, and so on. As long as we also modify the way that `price` manipulates the data before returning it, we have maintained the public interface despite changing the object internals.

## Classes

### The Class as code repository

Suppose our program makes use of two *OrderedCollections* — collections that store items in the order they were added. One keeps track of phone messages that we have received but not dealt with, and the other keeps track of things we must do — action items. Among others, we will need messages to add items to our collections, and to get the first item from a collection.

<footnote n="1">¹ Actually there is, but it involves meta-programming.</footnote>
We don't want to write `add:` and `first` twice, once for each object. Instead, we need a mechanism to write the code once so that it can be used by both `OrderedCollections`. This is where the concept of a *class* comes in. A *class* is basically a blueprint or a template for what the object looks like: what variables it has and what messages it understands. We define an `OrderedCollection` class and that's where we write the code for `add:` and `first`. So you can consider the `OrderedCollection` class to be a repository for the code that is executed when you send these messages. Write the code once, and all `OrderedCollections` (in our case, the two examples above), can execute the code.

The code is stored in a *method*. When an object receives a message, it executes a *method* with the same name. So, we write methods and the methods are stored with the class. Figure 1-2 shows an example of an `Employee` class, showing how the class acts as a template and as a code repository.

<figure><img src="image_3.png" /><figcaption>**Figure 1-2.**
The class as code repository.</figcaption></figure>

## The Class as factory

The next question is how our `OrderedCollections` are created. They don't appear by magic after all. The answer is that we ask the `OrderedCollection` *class* to create our two *instances* of an `OrderedCollection`. The following code shows two instance of `OrderedCollection` being created and assigned to variables (`:=` is the assignment operator).

```perl
phoneMessages := OrderedCollection new.
actionItems := OrderedCollection new.
```

So, besides being a repository for the code, the class is also a factory. Just as a car factory produces cars, an `OrderedCollection` factory (class) produces `OrderedCollections`. The factory contains blueprints for creating objects, and a template for what the object looks like — for the data it contains.

Now let's step back a moment and look at the code above which creates the instances of `OrderedCollection`. Notice that we send the `new` message to `OrderedCollection`. Remember that we get objects to do things by sending them messages. It looks remarkably like the `OrderedCollection` class is also an object, and in fact, this is the case. Not only are our individual instances of an `OrderedCollection` objects, but so is the factory that creates them. We give the name *class* to the factory object, and the name *instance* to each object that the factory creates. So in our example we have an `OrderedCollection` class which creates two instances of an `OrderedCollection`.
Because the class contains a template for individual instances of OrderedCollection, each OrderedCollection has its own copies of the instance variables firstIndex and lastIndex. And because the class is the repository for the code, each instance of OrderedCollection uses the code from the class.

## The Class as abstractor

A class abstracts out the common behavior and common data of the objects that it creates. It provides a place where the common behavior and common instance variables can be defined. The instance variables are simply slots; no data is contained in them until instances of the class are created. *A class is a factory with blueprints for the instances it creates. It is also a code repository.*

## Inheritance

Now let's look at another type of collection — a *SortedCollection*. Our action item list is better represented by a SortedCollection because we'd prefer to have all the high priority items appear before the low priority ones.

The big difference between a SortedCollection and an OrderedCollection is that in the former the items are sorted based on rules that you can specify. However, a lot of behavior is similar and therefore a lot of the code should be identical. It would be a shame to have to duplicate all the OrderedCollection code for a SortedCollection. Not only would it be a lot of work, but it would be a maintenance nightmare to also update the SortedCollection code if you make changes to OrderedCollection.

We would like an instance of SortedCollection to use the code that is already written for OrderedCollection, so that if the code changes, SortedCollections also get the changes. We would like to share the code where it makes sense to share, such as finding the first or last item in the collection. We'd like to have different code where the behavior is different, such as when adding an item to the collection. We would like a SortedCollection to *inherit* the behavior of an OrderedCollection where they are similar.

Fortunately we can do this by setting up an inheritance relationship between the classes. In the Object Oriented world, we can say that one class is a *subclass* of another class. So in our example, SortedCollection is a subclass of OrderedCollection. This allows SortedCollection to inherit all the code and instance variables of OrderedCollection. For example, if you want to loop through (iterate over) all the items in a SortedCollection, you send it the `do:` message, which is defined in OrderedCollection. SortedCollection inherits the code and its instance does exactly what an instance of OrderedCollection would do.

If you didn't write any specific code for a SortedCollection, it would inherit everything that is written for OrderedCollection. In fact, if we don't change some behavior, there's no point in having a new class at all. Fortunately, SortedCollections do have some different behavior. There are two types of different behavior. First, some messages need to do different things. For example, sending the `add:` message should add an object to the end of an OrderedCollection, but a SortedCollection should add the object in a position based on the sorting rule for the collection. If we do:

```
orderedCollection := OrderedCollection new.
orderedCollection add: 'xyz'.
orderedCollection add: 'def'.
orderedCollection add: 'abc'.
```
and inspect the collection, the strings will be ordered 'xyz', 'def', 'abc', in the order we added them. On the other hand, if we do:

```
sortedCollection := SortedCollection new.
sortedCollection add: 'xyz'.
sortedCollection add: 'def'.
sortedCollection add: 'abc'.
```

and inspect the collection, the strings are ordered 'abc', 'def', 'xyz', in the correct sort sequence for strings. So, in a `SortedCollection` we don't want to inherit our superclass's code for `add:`. Instead, we write our own `add:` method and override the one defined in `OrderedCollection`.

The second way we want different behavior is to add behavior — to do something that our superclass doesn't do. For example, we need to be able to specify the sorting algorithm that should be used by an instance of `SortedCollection`. We add behavior very easily, simply by writing a new method for `SortedCollection`. In the example of a sort algorithm, we write the `sortBlock:` method which stores the new algorithm for future additions and also resorts the collection according to the new algorithm. Figure 1-3 shows an example of inherited, overridden, and added methods.

<figure><img src="image_4.png" /><figcaption>Figure 1-3. Inheritance.</figcaption></figure>

## Polymorphism

Remember the `add:` message that is different for `OrderedCollection` and `SortedCollection`? There are other types of collection such as `Set`, `Bag`, and `LinkedList`, each of which implements its own version of `add:`.

What this means is that you can have a collection and not care much what type of collection it is; you simply send it the `add:` message and it will add an object to itself in the appropriate way. Another example might be a window that displays graphical objects. Rather than have the window know how to display a circle and a square, the window would simply send a message to the graphical object (for example, `graphicalObject displayYourselfOn: self`). The `graphicalObject` might be a square or circle, but the window doesn't care. It simply sends the same message regardless, and relies on the `graphicalObject` knowing how to display itself. In a procedural language you might write something like:

```pascal
if (graphicalObject isSquare)
    displaySquare (graphicalObject)
else if (graphicalObject isCircle)
    displayCircle (graphicalObject)
```
Using polymorphism, we might simply write:

```python
graphicalObject displayYourselfOn: self.
```

To use another example, we might have an Office object which sees Person objects coming in to work. One approach would be for the Office object to ask the Person object what kind of person it is. If it is a Programmer object, the Office object would tell it to start programming (`programmer startProgramming`). If it is a Receptionist object, the Office object would tell it to answer the phones (`receptionist answerPhones`). If it is a Manager object, the Office object would tell it to shuffle papers (`manager shufflePapers`).

This approach has the disadvantage of having a lot of code whose sole purpose is to check what type of Person object just walked in, then having to modify this code when a new type of person is added to the program. The better approach is for the Office object to have no interest in the type of person that walked in, and to simply tell the person to get to work (`person getToWork`). If a Programmer object receives this message, it will start programming; If a Receptionist object gets the message, it will start answering phones; if a Manager object gets the message, it will start shuffling papers. Now when you add a new type of person object, you just have to make sure that it responds to the `getToWork` message and does the appropriate thing. We have put the responsibility where it belongs. Figure 1-4 shows an example of polymorphism.

<figure><img src="image_5.png" /><figcaption>Figure 1-4. Polymorphism.</figcaption></figure>

This ability to have the same message understood differently by many objects means that we can get out of *decision making* mode and into *commanding* mode. This is a fundamental difference between procedural thinking and object-oriented thinking. Interpreting the same message differently is called *polymorphism*. It works because of the difference between a *message* and a *method*. When a message is sent to an object, the object looks up the message name (*selector* in Smalltalk terms) in the list of messages it responds to. Associated with the message selector is a method — some lines of code that will be executed. So, the same message selector will be associated with different code for different classes.

To me, the defining feature of object-oriented programming is the ability to simply tell an object to do something, rather than getting information then doing different things based on the information. Polymorphism is a key part of this ability. We'll go into some explicit techniques in Chapter 28, Eliminating Procedural Code.
## Abstract Superclasses

Now let's extend the idea of inheritance. OrderedCollection is a subclass of SequenceableCollection. Other subclasses of SequenceableCollection include ArrayedCollection and LinkedList. OrderedCollections, Arrays, and LinkedLists have some common behavior which has been coded in the class SequenceableCollection. However, you can't actually create an instance of SequenceableCollection (well you can, but you'll get errors if you try to do anything with it).

The class SequenceableCollection exists as a place to put the code that is common to the classes just mentioned. The common behavior has been abstracted out and placed in an abstract superclass, one that should not be instantiated — i.e., should not create instances of itself. For example, the methods `copyFrom:to:` and `occurrencesOf:` are both written in SequenceableCollection and inherited by its subclasses.

So, an abstract superclass is a class that has no instances of itself, but which exists as a repository for common code. The abstract superclass SequenceableCollection itself has an abstract superclass, *Collection*. *Collection* is also the superclass for *Set* and *Bag*, collections that don't have the concept of a sequence. Collection provides behavior that is common to all collections, such as `empty`, `collect:`, `do:`, and `includes:`. (Some of the subclasses override these methods to provide a more appropriate implementation for themselves. However, many of the subclasses inherit the behavior directly.) Figure 1-5 shows a small part of the Collection hierarchy.

<figure><img src="image_6.png" /><figcaption>**Figure 1-5.**
The Collection hierarchy.</figcaption></figure>

## Summary

* Objects encapsulate data and behavior (code).

* Classes are factories that have blueprints for creating instances. They are repositories for the code that is executed by their instances.

* Classes are arranged in an inheritance hierarchy that allows objects to inherit behavior (and code) from other classes up their hierarchy chain.

* Work gets done by objects sending messages to other objects, telling them to do something or to return something.

* Many different objects understand the same message but do different things when they receive the message. That is, they execute different methods (polymorphism).
2

Messages

As we said in the previous chapter, we send *messages* to objects to get them to do things. There are three flavors of message in Smalltalk.

Unary Messages

A unary message is a message with no arguments. For example, to negate the sign of an integer we would
send the unary message, negated.

4 negated

Binary Messages

A *binary* message looks just like an arithmetic operator. It gets the name *binary* because there are exactly two objects involved.

5 + 3

Here we are sending the + message to 5 with 3 as the argument. Unlike most languages where +, -, *, etc., are
operator symbols associated with algebraic operations, in Smalltalk they are messages with exactly one
argument. The binary messages are

+ - * / ** // \\ < <= > >= = ~= == ~ ~ & | , @ ->

Many of these are obvious, so I'll just explain the not so obvious ones.

** Exponentiation

// Integer division, rounding to the next lowest number.

\\ Modulo, returning the remainder after the division.

~= Not equal.

= Identically equal — ie, the same object.

~~ Not the same object.
& Logical AND, returning true if both the receiver and the argument are true. The receiver and argument are both evaluated, so it may be better to use `and:`, which only evaluates as much as is necessary and is also compiled in-line. Note that for both `&` and `and:`, if the receiver is true, the argument is returned, which may or may not be a Boolean.

| Logical OR, returning true if either the receiver or the argument are true. The receiver and argument are both evaluated, so it may be better to use `or:`, which only evaluates as much as is necessary and is also compiled in-line. Note that for both `|` and `or:`, if the receiver is false, the argument is returned, which may or may not be a Boolean.

, Concatenate two collections. Usually used to concatenate strings.

@ Used to create an instance of the Point class.

-> Used to create an instance of the Association class.

## Keyword Messages

We still need to be able to other types of messages with one argument and messages with more than one argument. The keyword message lets us do this. For example:

```
'elephant' copyFrom: 3 to: 5
```

gives the string 'eph' (Smalltalk collections are 1 based rather than 0 based as in C and C++; ie, the first element in the collection is referenced by index 1). The colons separate out the keywords in the message, where each keyword takes an argument. (In strict terms, `copyFrom: 3 to: 5` is the message and `copyFrom:to:` is the message selector, but we will also refer to `copyFrom:to:` as the message.)

## Message chaining

Methods always return an object (more on this later). This means that you can chain messages together, because there is guaranteed to be an object to send each message to. For example, the following returns -3.

```
3.14 truncated negated
```

When the floating point number receives the `truncated` message, it returns a `SmallInteger`, which in turn returns another `SmallInteger` when sent the `negated` message. Another example might be a string that contains a number. We want to change the sign on the number and convert it back to a string. One option would be to say:

```
number := '42' asNumber.
negatedNumber := number negated.
string := negatedNumber printString.
```

However, because each method returns an object, we can write this as:

```
string := ( ( '42' asNumber ) negated ) printString.
```

or we can leave out the parentheses since we are dealing only with unary messages, all of which have the same precedence.

```
string := '42' asNumber negated printString.
```
## Message precedence

Unlike C++, which has very complicated rules of precedence, Smalltalk has very easy rules:

1. Evaluation is done left to right.

2. Unary messages have the highest precedence.

3. Binary messages have the next precedence.

4. Keyword message have the lowest precedence.

5. You can alter precedence by using parentheses.

One thing that is immediately different from most languages is that there is no algebra. `+` and `*` are not algebraic symbols — they are simply messages. Using the precedence rules above,

$$1 + 2 * 3$$

equals 9, not 7. To get the result you would expect, you have to use parentheses to specify the precedence.

$$1 + (2 * 3)$$

To give two more examples, `2 + '4' asNumber max: 5` gives 6, because by the above rules, the unary `asNumber` is sent first, giving `2 + 4 max: 5`. Then the binary `+` is sent, giving `6 max: 5`, which returns 6.

The computation `30 max: 3 + 4 * 5` gives 35. There are no unary messages, so the binary messages are sent in left to right order. With the first message sent, we get `30 max: 7 * 5`. With the next binary message sent, we get `30 max: 35`, which returns 35. To get an answer of 30, as you would expect from normal algebra, you would have to use parentheses such as `30 max: 3 + (4 * 5)`.

## What happens when a message is sent

When a message is sent to an object, the Smalltalk system looks to see if a method with that name exists for that type of object (in other words, has been written and stored in the class of the object). If there is a method, it is executed. If no method of that name is defined in the object's class, the system looks in the method dictionary for its immediate superclass. If there is no method with that name in the superclass it looks in the superclass's superclass. Figure 2-1 illustrates this.
<figure><img src="image_7.png" /><figcaption>**Figure 2-1.**
The method lookup mechanism.</figcaption></figure>

The method lookup keeps working its way up the superclass hierarchy until it finds a method with that name, which it then executes. If it reaches `Object` and still doesn't find a method, it displays a ` Notifier` window that gives you an opportunity go into a ` Debugger` and figure out what went wrong<fnref n="1" />.

## The receiver of the message

All messages have to be sent to an object — there's no such thing as a message in isolation. If you create an object in a method, it's easy to send a message to the object. For example:

```
MyClass::doThis
    array := Array new: 3.
    array at: 1 put: 2.
```

(The generally used notation to show instance side method names is `ClassName>> methodName`. For class side methods, the notation is `ClassName class>> methodName`.)

## self

Smalltalk methods average about seven lines, so for an object to do any serious work there's a good chance that you will have split the work into several methods (assuming you want to have short methods). How does a method invoke another method defined on the same object? Answer: the object sends a message to itself. Smalltalk has a special variable for just such use — `self` — which always refers to the object that is executing the code — the message receiver. Note that `self` refers to the receiver even if the code was defined on a superclass of the receiver's class.

```
MyClass::processObject: anObject
    self doThisWithObject: anObject.
    self doThatToObject: anObject.
```

<footnote n="1">¹ What actually happens is that if a method is not found, the `doesNotUnderstand:` message is sent. Unless this has been overridden, the `doesNotUnderstand:` method tells `Object` `messageNotUnderstoodSignal` to raise an exception. Unless you have a `handle:do:` block to trap this exception, the exception is unable to find a signal handler and it gets converted into another exception (an unhandled exception exception) which invokes the `EmergencyHandler`. Unless you have overridden the behavior of the `EmergencyHandler`, it opens a ` Notifier` window.</footnote>
If a method needs to call on a support method to do some work, send the message to self. In fact, a good rule of thumb is, if you can't figure out what object to send the message to, send it to self.

## super

If you remember how message lookup works, Smalltalk looks for the method first in the object that is receiving the message. If it can't find a method there, it next looks in the superclass, etc. But what do we do if we explicitly want to start looking in our superclass? Smalltalk provides another special variable, `super`. So, if you want to start at your superclass, send a message to `super`.

When would this be useful? One common example is during instance creation. If you want to initialize some instance variables you usually write an `initialize` method on the instance side. You can no longer inherit `new` since it doesn't send `initialize`, so you have to write your own `new` method, which will inherit the behavior of `new` from a superclass. Note that the caret (`^`) shown below means `return`.

```java
MyClass>>initialize
... set some variables ...

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

In fact, `super` does *not* refer to the superclass of the object that received the message. Instead, it refers to the superclass of the object that defined the code being executed. It's a subtle difference but an important one because if it were not this way it would be easy to end up in infinite recursion. Let's look at why. Let's say we have a class hierarchy with `ClassTwo` subclassed off `ClassOne`, and `ClassThree` subclassed off `ClassTwo` as shown in Figure 2-2.

<figure><img src="image_8.png" /><figcaption>**Figure 2-2.** The ClassOne, ClassTwo, ClassThree inheritance hierarchy.</figcaption></figure>

All three classes have instance variables that must be initialized and the initialization code looks like the following.

```java
ClassOne>>initialize
... set some variables ...

ClassTwo>>initialize
```
super initialize.
... set some variables ...

ClassThree>>initialize
super initialize.
... set some variables ...

When we create an instance of ClassThree and execute the ClassTwo initialize code from the ClassThree object, what does *super* refer to? If it refers to the superclass of the class *executing* the code, then *super* will be ClassTwo and the *initialize* message will be again sent to ClassTwo. Ie, we'll end up in an infinite loop. On the other hand, if *super* refers to the superclass of the class *defining* the code, the message will be sent to ClassOne and everything works fine.

A key point to note is that *self* has an identity of its own and can be inspected, assigned to a variable, and passed as a parameter. However, *super* has no identity and you cannot inspect it or assign it. When you accept a method, the compiler compiles the method text into byte codes. When it comes across the word *super* it generates byte codes that instruct the run-time engine to start the method lookup in the superclass of the class *defining* the method. Thus *super* is simply a mechanism for telling the compiler how to generate byte codes.
Methods contain code that is executed in response to message sends. Unlike functions in C or C++ which can be void functions, in Smalltalk all methods return a value. If there is no explicit return value, the method will return `self`, the object executing the method.

## Method Types

There are two basic type of method: ones that return an object other than `self`, and ones that cause an effect. Examples of the first type are `asSortedCollection`, which converts a collection into a sorted collection and returns this, and `printString`, which returns an object that is a printable representation of the object receiving `printString`. Examples of the second type of method are printing to the Transcript (eg, `Transcript show: 'hello'`), and updating a file with data.

As a general philosophy, it's better to try and make your methods one type or the other. Try to avoid methods that both do something and return a meaningful object. Sometimes it will be unavoidable, but less often than you might expect. Unlike languages where you have to check the status returned from a function call, Smalltalk provides an exception handling mechanism that allows you to bypass the whole status checking aspect of error handling.

## Method Length

In the VisualWorks class library, the average Smalltalk method length is reputed to be seven lines. A short method is a good method because it makes it easy for programmers to understand what the method is doing. A short method is also easier to reuse and easier for subclasses to override in order to modify the behavior. For these reasons it is a good idea to define a "standard" sized browser and have a guideline that all methods should fit in the browser window. If a method is larger, it's usually possible to break it into smaller methods by abstracting out the concepts of what you are doing and putting each concept in its own method. For example, a long method may end up as a short method such as:

MyClass>>myMethod

Copyright © 1997 by Alec Sharp

Download more free Smalltalk-Books at:

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

- European Smalltalk Users Group: http://www.esug.org
```kotlin
self myDoConceptOne.
(someCondition)
ifTrue:
    [self myDoConceptTwo]
ifFalse:
    [self myDoConceptThree.
self myDoConceptFour]
```

## Method names

Because short methods that fit in a screen can be more easily understood, it doesn't make sense to prevent that understanding with poor names. Use method and variable names that are as explicit as possible. Don't abbreviate words unless they are standard abbreviations understood by everyone working on the project. Since you don't type names very often in Smalltalk, it doesn't hurt to make them long enough to be very explicit and understandable.

Method names should say exactly what the method does. Don't be stingy with the number of characters; it's more important to be understandable than short. A programmer should be able to pick up someone else's code and immediately know what the method does, just be reading the name. However, it's not always easy to come up with a great method name when you are looking at the method itself. It's when the method is being invoked, when you are doing the message send, that you'll get the best idea of how good the name is. If it makes sense in the context where it is sent, then you've probably got a good name. So, while it's okay to name the method when you are writing it, be prepared to go back and change the name after you use it in other methods.

## Stupid methods

If a method is short, has a good name, and has well thought out names for its variables, it will be fairly understandable. If class comments describe the general behavior of the object and describe the instance variables well, a good method doesn't need much comment. I really like the idea of *stupid methods*. (I'd like to give credit to the creator of the term but unfortunately I can't remember where I read about the idea.)

A stupid method is one that is so obvious that it doesn't need any documentation. The problem with documentation is that it makes a method longer, so if you have a method that is long enough to need some serious documentation, you compound the problem by making it longer and less able to fit on a screen. Not fitting on a screen, it is less readily grasped by a programmer. The ultimate compliment of a method is "that method is really stupid."

## Method formatting

The formatter does a pretty good job of formatting methods for you. My rule is to ignore formatting when I'm creating a new method, then to run the formatter. If I don't like what the formatter does, I'll reformat the code by hand. Here are a few examples of how I might reformat when I don't like the formatter results. To save space I won't show the original formatting; to see it, you'll have to type in the code and run the formatter.

```kotlin
myMethod: aParameter
aParameter
doThis;
doThat;
doSomethingElse
```
```kotlin
myMethod: aParameter
    self errorSignal
    handle: [ :ex | ex return]
    do:
        [aParameter doThis.
         aParameter doThat]

myMethod: aSource and: aDestination
    (aSource location = aDestination location)
    ifTrue: [self errorSignal
              raiseWith: #sourceEqualsDest
              errorString: 'This is an error string'].
```

Some people find the formatter's format too difficult to read, especially in the case of complex, nested code. An approach preferred by some is to put each closing square bracket on its own line. The trade-off is that it becomes less likely that a method will fit into one screen, which is a strong goal of mine. One answer is that if the code is difficult to read, the method is very likely too long, too complex, or both. So you might call the formatter a benefit if it forces you to refactor your code to make it more elegant and comprehensible.

To improve clarity it's often worth putting in redundant parentheses. A programmer looking at code and working through the message precedence rules can always figure out what is happening, but you can shorten the process if you add parentheses to group things. Since the formatter removes redundant parentheses but leaves required parentheses, you can also use it to tell you where parentheses should be. For example, the first conditional below causes an exception, the second conditional shows what you intend, and the third conditional is what the formatter gives you when you format the second conditional. If you had something more complex, it might be worth leaving the extra parentheses in.

```
a < b | c < d
(a < b) | (c < d)
a < b | (c < d)
```

## Public and Private methods

In C++ there is the notion of public and private functions. Public functions are ones that any object can invoke. Private functions are ones that are accessible only to instances of the class that defines them, or its subclasses (actually protected functions in the latter case).

Smalltalk does not have such a concept. All methods are accessible to all objects — they only have to send the correct message. However, the notion of public and private methods is useful; you really don't want other objects sending messages that exist only to help with the implementation details. Suppose you decide to change the way something is implemented. You don't want to have to preserve all the private interfaces. You want to be able to encapsulate behavior so that other objects can use the public interface and you can be free to change the implementation details.

Because there are no private methods in Smalltalk, any distinction between private and public methods has to be made using standards. One standard is to use the word *private* in the protocol names for private methods. You might see a protocol named *private* or *private-accessing*. The disadvantage of this scheme is that you don't always notice the protocol name. If you are browsing methods using senders, implementors, and messages, you are not told the protocol so may easily decide to use a particular message.
The technique I like is one described by Bob Brodd in The Smalltalk Report, Nov-Dec, 1994. All private methods are prefixed with `my`. Now you use common sense English to prevent the public use of private methods. Basically it looks strange to see something like `anObject myDoThis`, whereas it looks reasonable to say `self myDoThis`. If you ever see a `my` message sent to anything other than `self`, be suspicious — you are probably seeing a private method being used as if it were public. Here's an example of using the `my` prefix for private methods.

```
ImageCreator>>createImage
    self myRemoveSelfAsDependent.
    self myFileInApplication.
    self myRunStripper.
    self myOpenApplication.
    self myCloseLauncher.
    self myInstallEmergencyHandler.
    self mySaveImageAndQuit
```

If you use the `my` technique, there are two basic approaches you could take. One is to make everything public unless you know it is a support method that shouldn't be invoked in isolation. The other is to start by making all methods private, then making them public as you come across a message that needs to be sent by another object.

The advantage of the first approach is that you can't predict how other people will want to use your class, and if you make methods private by default, you don't give people the opportunity to be fully creative. The advantage of the second approach is that by making methods private by default, you define a public interface to your object and don't open up the implementation details to other objects. I generally use the latter philosophy because I want my objects tightly encapsulated. However, I also make the distinction between domain specific objects and general reusable objects; the latter usually have more public methods.

We can extend the concept of `my` methods to include `friend` methods. A `friend` message is one that can be sent between friend objects. Suppose you have a nicely encapsulated subsystem that consists of several collaborating objects. None of these objects has a life outside the subsystem, and they don't expect to receive messages from objects outside the subsystem. We can consider these objects all friends of each other, and define a prefix such as `fr` to denote messages that can only be sent by a friend. Each class that defines `friend` methods would have to provide documentation in the class comments describing exactly which classes are friends. Any programmer wanting to use a message starting with `fr` would have to look at the class comments to find out if the sending object is actually a friend.

In Chapter 29, *Meta-Programming*, we will show an extension to *Class* that automatically creates both public and private accessors for all our instance variables when we define a class.

## Returning from a method

In Smalltalk, all methods return a value. There is no such thing as C++'s `void` function. By default all methods return the object the message was sent to. So, if there is not an explicit return in a method, in effect the last line of the method looks like:

```
^self
```

`^` is the return symbol and `self` refers to the message receiver — the object executing the method. Most methods implicitly return `self`. In the VisualWorks Browser, if you hold the `shift` key down while selecting a
method with the mouse you will see the decompiled code, which actually has a `^self` at the end. The return (`^`) is executed after all other message sends and assignments in the statement have been done.

## Return object defined by method name

Often the method name will tell you what type of object will be returned. For example, method names that start with `is` will usually return a Boolean, true or false. For example, `empty?`, `isNil`. Messages that start with `as` will usually return the thing specified. For example, `asSortedCollection` sent to a collection will return a SortedCollection. The `asNumber` message sent to a string will return a number of the appropriate type. (However, `asString` is not implemented by numbers so you should use `printString` or `displayString` instead.)

Methods that add objects to collections, such as `add:` and `at:put:`, return the object that is added. Methods that remove single objects from collections, such as `remove:` and `removeFirst`, return the object that was removed. Because of this it's worth knowing about the `yourself` message. The following example illustrates how the use of `yourself` ensures that `collection` contains the list rather than the last object added (the example makes use of message cascading, which we will talk about in Chapter 6, Special Variables, Characters, and Symbols).

```perl
collection := List new
    add: thisObject;
    add: thatObject;
    yourself.
```

Consistency and predictability are great virtues, so when adding these types of methods to your own classes, follow the common usage patterns. Otherwise you'll confuse every programmer who looks at or uses your code.

## Return object defined by last statement

If a method returns something other than self, the last line or the last statement in the method will specify what is being returned. The assumption when you see an explicit return at the end of the method is that the message sender will care about what is being returned. For this reason, don't do `^self` at the end of the method unless this has an explicit meaning for the sender.

## Guard clauses

If you will execute the method body only if some condition is true, the obvious way to do this is:

```perl
MyClass>>someMethod
(some condition) ifTrue:
    [self doThingOne.
     self doThingTwo.
     self doMoreLinesOfCode]
```

However, it is often better to return self from an `ifFalse:` block, then execute the main code. Thus we have a *guard clause* protecting entry to the method.

```perl
MyClass>>someMethod
(some condition) ifFalse: [^self]
```
self doThingOne.
self doThingTwo.
self doMoreLinesOfCode]

This makes the code a little easier to follow because it's all straight line code rather than conditional. This approach goes against the structured programming adage of one entry point, one exit point. The rule was created to solve the understandability problem of long functions with multiple entry and exit points. However, Smalltalk methods are usually short, so it's easy to see exactly what is happening.

## Consistency in objects returned

If your methods implicity returns `self` at the end, use `^self` to return earlier. Don't return a different value, such as `nil`, unless `nil` has a specific meaning to the sender.

## Misplaced Methods

If a method doesn't reference any instance variables, and simply operates on parameters, you might ask if the method is defined in the right place. If the method is manipulating a parameter, perhaps the code should be defined by the class of the parameter. For example, when working with a string, you may decide you need to remove the leading and trailing white space. So you write a new method for your class that trims the white space.

MyClass>>removeWhiteSpaceFrom: aString
... remove leading and trailing white space...
^newStringWithWhiteSpaceRemoved

However, this is a very procedural way of writing code. If you are thinking in terms of objects, you figure out where the responsibility really lies, and tell objects to do things. Since *MyClass* really is not responsible for removing white space from strings, where should that responsibility lie? The most obvious place is the class *String* (or one of its superclasses). You can then tell your string to strip itself of white space.

trimmedString := aString trimWhiteSpace.

## Number of Methods

There is no rule for how many methods an object should have, but if you find that one object has many more methods than other objects, it may be that you are not distributing the workload well. In a good Object-Oriented system, you don't have super-intelligent objects. Instead, you have many peer-type objects cooperating. For more information, see Chapter 9, Object-Oriented Thinking.

## Defaulting Parameters

In C++, you can leave out parameters in function calls and the parameters will be defaulted (assuming the function is written this way). In Smalltalk no such capability exists. Instead, you often see a method do nothing other than invoke another method with an additional parameter.

A good example of this is the *changed* message. When you invoke the dependency update mechanism, you use *changed* to specify that something has changed. You use *changed*: to specify what has changed, and *changed:with*: to specify the new value.
Object>>changed
self changed: nil

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

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

Method Template

The method template (what you see when you are looking at methods but don't have a method selected) is
defined in `Behavior>>sourceCodeTemplate`. If you don't like it, you can change it. For one example of
how you might change it, see Chapter 31, Customizing your Environment.
4

Variables

In this chapter we'll look at the different types of variable that are available in Smalltalk: instance, class, class instance, parameter, and temporary. Global variables are a big enough topic in themselves that we cover them in Chapter 7, Global Variables. Smalltalk also has a few special variables that we will see in Chapter 6, Special Variables, Characters, and Symbols.

Variable names

Code is easier to understand when all method names and variable names are meaningful and easy to
understand. Make variable names explicit and obvious so that a reader immediately knows the purpose of the
variable. Don't abbreviate names; spell them out in full unless there are abbreviations that are accepted by all
programmers and are part of the project vocabulary. Your goal should be that a programmer can look at your
code and immediately understand what is going on, even without comments in the code. Part of this involves a
good division of responsibility in the code and part involves well thought out names for methods and variables.

Variable names consist of one or more words strung together. The first letter of each word should be capitalized, and the rest of the letters should be lowercase. The exception to this is the first letter of the name for which the following rule applies: Instance, parameter, and temporary variables should start with a lowercase letter. Class, class instance, and global variables should start with an uppercase letter. Some people leave acronyms as uppercase; I try to avoid having two capital letters in a row as it makes it just that little bit harder to break the name into words. Here are some examples of variable names.

"Instance or temporary variables"
employeeName
collectionOfStrings
upperLeftCornerOfBox

"Parameter"
aNumber
aCollectionOfEmployees

"Class, Class instance, or Global variables"
Employee
DaysInMonth
MonthNames

I've always found it useful to prefix class names with an application or component prefix because I like to know where a class comes from when I see it in the code. For example, if you have an accounting application with payroll, accounts payable, and general ledger components, you might have prefixes such as `Pr`, `Ap`, `Gl` for the components, then something like `Aac` for the classes used for the communication between components (Accounting Application Communication). General support classes that will be used across applications or components get a general company prefix, or a prefix such as `Sup`.

## Instance variables

Suppose we have a class called *Friend*. Each friend in our application has a first name, a last name, and a phone number. The class definition for *Friend* specifies that each instance of *Friend* has three variables: *first Name*, *last Name*, and *phone*. We specify these *instance variables* in the class definition.

```python
Object subclass: #Friend
    instanceVariableNames: 'first Name last Name phone'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'My-Category'
```

When we create a new instance of *Friend*, it will have its own values in the instance variables. We might create an instance of *Friend* by sending the following instance creation message to the class *Friend*.

```python
friendOne := Friend
    newLast Name: 'Doe'
    first Name: 'John'
    phone: '555-5555'
```

If we then create another friend, `friendTwo`, it has no effect on `friendOne`, because `friendOne` has its own values in the instance variables.

```python
friendTwo := Friend
    newLast Name: 'Smith'
    first Name: 'Jane'
    phone: '111-1212'
```

The two instances of *Friend* have their own values in the instance variables, independent of the values in the other instance. If we change the value of one instance variable, it has no effect on the other friend. For example, we can change the phone number for John Doe without affecting the phone number of Jane Smith.

## Class variables

Suppose we have several instances of class *Date*. Each instance will be unique, and will have its own values for the instance variables defined by *Date* (these are *year*, the year, and *day*, the number of days since the beginning of the year). We want to know the name of the month for each of these instances. Something has to keep track of the names of the months, and since month names are associated with dates, we might as keep track of the names somewhere in the *Date* class. However, we don't need to waste space by having each instance of a *Date* keep this array. Instead, we put the array of month names in a *class variable*. This lets the *Date* class keep
track of the array, so we only have one copy of the array. All instances have access to the class variables of their class, so each instance of *Date* can access the month name array. In fact, *Date* has many class variables, as shown in the following class definition.

```java
Magnitude subclass: #Date
    instanceVariableNames: 'day year '
    classVariableNames: 'DaysInMonth FirstDay Of Month MonthNames
SecondsInDay WeekDayNames '
    poolDictionaries: ''
    category: 'Magnitude-General'
```

Here are two examples where instances of *Date* reference some of the class side variables. The messages `monthName` and `daysInMonth` look at the arrays held in the class variables `MonthNames` and `DaysInMonth`.

```
(Date newDay: 115 year: 1960) monthName. #April
Date today monthName. #October
Date today daysInMonth. 31
```

All instances can directly reference their class variables, although it may be preferable to reference them through *accessors*, which we'll look at later in this chapter. Although instances have access to the class variables of their class, the class itself does not have access to any instance variables of its instances, and in fact, the class doesn't usually even know that it has instances. You can inspect the class variables of a class by inspecting the class then inspecting the *classPool* variable<fnref n="1" />.

## Classes referencing their instances (advanced)

Despite the fact that classes don't by default know about their instances, you will sometimes find that classes manage their instances. You may also find that there is a concept of the *current* instance of a class. Combining these concepts (which doesn't usually happen), you might see something like the following in a class definition. Note that what we describe here is very simplistic and is just designed to point out the concepts.

```java
Object subclass: #MyClass
    instanceVariableNames: 'instVar1 instVar2 '
    classVariableNames: 'Instances Current '
    poolDictionaries: ''
    category: 'MyCategory'
```

When a new instance is created, it is stored in a collection of instances held by the *Instances* class variable. There is also a method to retrieve and set the current instance so that the rest of the system knows which instance of *MyClass* they should be working with.

```java
MyClass class>>initialize
    "self initialize"
    Instances := OrderedCollection new.
```

<footnote n="1">¹ Alternatively, you can send the *classPool* message to the class (eg, *Date classPool*). If you know the name of the class variable, you can do something like *Date classPool at: #DaysInMonth*. (Interestingly, you can inspect the class variables of Object directly, just by typing the variable name in a text window such as a workspace or a Browser, then inspecting the name. This works because in a text window, *self* is either *nil* or the class that you are browsing. Because of inheritance, both of these objects have direct access to the class variables of their superclasses, and so can see the class variables of Object.)</footnote>
MyClass class>>new
"This shows the concepts"
newObject := super new initialize.
Instances add: newObject.
^newObject

MyClass class>>new
"This shows a tighter implementation"
^Instances add: super new initialize.

MyClass class>>current
^Current

MyClass class>>current: anInstance
"Set the current instance and inform dependents, telling them the
old value"
old := Current.
Current := anInstance.
self changed: #current with: old

This last method shows some code associated with the Smalltalk dependency mechanism. We'll see more
about this in Chapter 19, The Dependency Mechanism, but for the time being we'll simply remark that it
provides a way for other objects to be told when the current instance has changed and gives them a chance to
take whatever actions are meaningful for them as they change to the new current instance.

Class instance variables

Besides class variables and instance variables, Smalltalk provides a variable called a *class instance variable*.
It's a variable defined on the *class* side, and provides a way to hold a value that is potentially different for each
subclass of the original class. Instances of each subclass all have access to the variable, but instances of one
subclass will see a different value than will instances of another subclass.

It's not very common to see examples of class instance variables, but they can be useful. Here's an example of
one such use. Suppose that your application has a centralized error message facility (we talk more about this in
Chapter 20, Error Handling). However, each component of the application wants to have its own error messages
and its own numbers, each prefixed by the appropriate tag. By having separate subclasses for the different
components, programmers can work on the components in isolation without having to worry about message
symbol or number conflicts. The component error messages classes are subclassed off *ErrorMessages*. Note that
all the definitions and methods below are on the class side.

ErrorMessages class
instanceVariableNames: 'Messages'

ErrorMessages class>>initialize
Messages := Dictionary new.

ErrorMessages class>>number: aSymbol
^(Messages at: aSymbol ifAbsent: [self notFoundError: aSymbol])
key printString

ErrorMessages class>>notFoundError: aSymbol
^0->('Symbol <', aSymbol, '>' not found')

ComponentOneErrorMessages class>>initialize
<table><tr><td>super initialize.</td><td></td></tr><tr><td>Messages</td><td></td></tr><tr><td>at: #notFound</td><td>put: 1 -> 'Account not found';</td></tr><tr><td>at: #duplicate</td><td>put: 2 -> 'Duplicate account'.</td></tr></table>

ComponentOneErrorMessages class>>number: aSymbol
'^C1-', (super number: aSymbol)

<table><tr><td>super initialize.</td><td></td></tr><tr><td>Messages</td><td></td></tr><tr><td>at: #duplicate</td><td>put: 1 -> 'File already exists';</td></tr><tr><td>at: #notFound</td><td>put: 2 -> 'File not found'.</td></tr></table>

ComponentTwoErrorMessages class>>number: aSymbol
'^C2-', (super number: aSymbol)

To sum up, class instance variables are used when you need a class variable to store information that may be different for each subclass. We show another use of class instance variables in Chapter 30, Testing, where we use them to hold the display name of the test case subclasses.

## Parameters

Parameters (or arguments) are objects that are passed into a method or a code block. Smalltalk doesn't have type checking, so you can pass any object as a parameter to any method. Of course, when you send a message to the parameter object, there will be problems if the object doesn't understand the message — if the object is not of the appropriate type. (Some people jokingly say that Smalltalk is very strongly typed — all arguments must be objects!) Unlike the other types of variable, you can't assign a different value to a parameter variable. Fortunately, the compiler will catch this, so you won't even be able to accept the following.

MyClass>>doSomethingWith: anObject
anObject := 3.

However, you can modify the contents of a parameter, so it's perfectly legitimate to do the following, although not necessarily good style.

MyClass>>modifyCollection: aCollection
aCollection add: 3.

## Method parameters

In the code shown above, we've seen various examples of messages and parameters. Shown below are a few examples of method and parameter names as shown in the various definitions.

Date class>>newDay: dayCount year: referenceYear
Object>>changed: anAspectSymbol with: aParameter
OrderedCollection>add: newObject
Dictionary>>at: key put: anObject
MyClass>>modifyCollection: aCollection

The objects after the colons are the parameters. Why do the parameters have these names? There are two types of naming scheme: you can name the parameter according to its *content* (eg, *last Name*, *salary*, *price*, *quantity On Hand*), or according to its *type* (eg, *anInteger*, *anArray*, *aSymbol*) As a general rule you'll find
instance and temporary variables named according their content, while method parameters are named according their type. You'll often see methods that have parameters with names such as *aString*, *aCollection*, *anEmployee*, *aRobot*. This type information tells the programmer a lot about the messages that can be sent to the object. Sometimes, however, *type* information is not enough.

In the examples above, the parameter to `newDay`: could have been `anInteger`, but this would provide very little information about what the content of the integer should be. So, the parameter is named `dayCount`. Similarly, we might have a method that creates a new instance of *Employee* as follows.

Employee class>>firstname: firstname lastname: lastname

It makes more sense to give the parameters names such as *firstname* and *lastname* rather than *aStringOne* and *aStringTwo*. Even names such as *aFirst Name String* don't add a lot of information, especially since the method will probably not do anything with the parameters other than store the values in instance variables.

To summarize, method parameters are often named according to their type. However, there will be situations where naming them according to their content makes more sense, and situations where naming them according to a mixture of type and content makes sense.

## Block parameters

Code blocks contain code that is not executed until the block is sent a message from the *value* family. To pass a parameter to a block, the message will have to be one that has a parameter, such as `value:` or `value:value:`. For example, we might have something like the following.

block ::= [ :nameString | Transcript cr; show: 'The name is ', nameString ].
block value: 'Alec'.

block ::= [ :nameString :age |
Transcript cr; show: 'The age of ', nameString, ' is ', age
printString].
block value: 'Dave' value: 12.

You probably won't often use blocks with more than one or two parameters, but if you do, you can send `value:value:value:` for blocks with three parameters, or `valueWithArguments: anArray` if you have more than three. For example, a block with five parameters might look like the following. If the number of array elements doesn't match the number of parameters, you'll get an exception.

[ :parm1 :parm2 :parm3 :parm4 :parm5 | self doSomething ]
valueWithArguments: #(99 88 77 66 55).

You'll see block parameters used in the enumeration methods of collections. For example,

aCollection do: [ :each | Transcript cr; show: each printString].
aCollectionOfNumbers collect: [ :each | each * 30].
aCollectionOfNumbers inject: 0 into: [ :subtotal :each | subtotal + each ].

When naming the parameters of a block that is used when iterating over a collection, one convention is to use the parameter name *each*. This tells you instantly that the variable is the current element of the collection.
Alternatively, use the name `index` if you know that the variable is an index, or the name `char` if the variable is a character in a string.

```clover
1 to: 5 do: [ :index | self doSomethingUsing: index ].
'now is the time' do: [ :char | self doSomethingUsing: char ].
```

Generally, the only time I would use a name other than `each`, `index` or `char` for the collection element is if there are nested collection iterations, and I can't use the same name in both of them. For example,

```clover
# ('cat' 'dog' 'gerbil')
collect: [ :pet | #('milk' 'water' 'oj')
collect: [ :drink | pet -> drink]]
```

## Temporary variables

Temporary variables are variables that exist only for a short time: for the duration of a method or the duration of a block of code. There are several reasons to use a temporary variable. The most important reason is to *capture a value that can't be regenerated*. For example, if you are reading an object from a stream or a shared queue, and you want to use that object several times, use a temporary variable to capture it. For example:

```clover
request := sharedQueue next.
originator := request originator.
requestTime := request creationTime.
```

Another reason to use a temporary variable is to *avoid having to repeat expensive operations*. For example, if you are comparing a variable with a value from a database, it's appropriate to store the database value in a temporary variable. Compare the two examples below.

```clover
aCollection detect: [ :each | each = self myValueFromDatabase ]
ifNone: [nil].

databaseValue := self myValueFromDatabase.
aCollection detect: [ :each | each = databaseValue ] ifNone: [nil].
```

A third reason to use a temporary variable is to *increase performance by reducing the number of message sends*. For example, in the first example below, we have to do several identical message sends several times. It saves a lot of message sends if we do it the way shown in the second example.

```clover
self checkAddress: (employeeCollection at: employeeId) address.
self validateSalary: (employeeCollection at: employeeId) salary.
self printCheck: (employeeCollection at: employeeId).

employee := (employeeCollection at: employeeId).
self checkAddress: employee address.
self validateSalary: employee salary.
self printCheck: employee.
```

A fourth reason to use a temporary variable is to *make it easier to understand the code*. Sometimes it can be difficult to understand what object we have as a result of a complex sequence of message sends. While we may not need to use a temporary variable if we only do this sequence of message sends once, it can make the code more readable to store the result of this sequence in a well named temporary variable. (An alternative approach is to compute the complex result in another method and replace the complex message sends with a single message
send.) For example, the code below makes it easy to see what is going on without having to read through the sort
block code.

MyClass>>mySortByBirthday: aCollection
| birthdaySortBlock |
birthdaySortBlock := [ :first :second | first birthday <= second
birthday ].
^aCollection asSortedCollection: birthdaySortBlock.

Temporary to the method

Temporary variables are named between vertical bars before any code in the method. For example,

copyWith: newElement
| newCollection |
newCollection := self copy.
newCollection add: newElement.
^newCollection

You can type in the temporary variable name between the vertical bars, or you can let the compiler generate the name between the bars. The compiler will generate the names of temporary variables in the order in which they occur in the method. I usually let the compiler generate the names, but this sometimes leads to problems. If you give a temporary the same name as an instance variable, the compiler will assume that you are referring to the instance variable and not generate the name for you. (If you type the name in yourself, you will be warned that a variable of that name already exists, perhaps in an outer scope). On the class side, if you name a temporary variable *name* and don't put it between vertical bars yourself, the class itself will be given a new name when the code is run!

Temporary to the block

Temporary variables in blocks are enclosed between vertical bars, just as method temporaries are. For
example,

[ | result |
result := self myDoSomething.
... ]

If you have block parameters and block temporary variables, they are defined as follows. Note that a vertical
bar appears after the parameters, and the temporary variables are defined between their own vertical bars. So
there are two vertical bars.

myMethod
aCollection do: [ :each | | result |
....

BlockClosures have better performance if all the variables they reference are local to the block. So, rather
than letting the compiler generate temporary variable definitions at the top of the method, look to see if it is
possible to make all block references internal to the block.
## Global variables

Chapter 7, Global Variables, covers global variables, so we won't discuss them here.

## Variables as slots

Variables are simply slots which hold an object. The object itself exists somewhere in computer memory, but it is *bound* to the variable. If we bind a different object to the variable, the first object may no longer be bound to any variable. When an object is not bound to any variable — ie, it is no longer referenced, the object is available to be garbage collected. In concept it is floating somewhere in memory with nothing attached to it, and the garbage collector comes along and sweeps it up.

Because an object exists separately and is just bound to a variable, there's no reason that an object can't be bound to many variables simultaneously. We could easily have a situation such as the following. When you inspect `d`, you'll see that it contains three items, the numbers 1 and 2, and 3. Multiple assignments, as shown in the example, are legal but bad style.

```
a := b := c := d := OrderedCollection new.
a add: 1.
b add: 2.
c add: 3.
d inspect.
```

In this example, we assign the same instance of OrderedCollection to all the variables. When we modify the collection via one variable, its contents are changed and that change is visible to all variables that have been bound to it. This is illustrated in Figure 4-1.

<figure><img src="image_9.png" /><figcaption>**Figure 4-1.**
All variables holding same object.</figcaption></figure>

On the other hand, if we were to do the following, we would find that `b` contains the number 2, while `d` contains the numbers 1 and 3.

```
a := b := c := d := OrderedCollection new.
a add: 1.
b := 2.
c add: 3.
b inspect.
d inspect.
```

In this example, we assign a different value to `b`, and bind it to the object 2 instead of the instance of OrderedCollection. This is illustrated in Figure 4-2.
<figure><img src="image_10.png" /><figcaption>**Figure 4-2.** Variables holding different objects.</figcaption></figure>

## Accessors

Accessors are methods that allow you to get and set the values of instance variables and class variables. Since instance variables are more heavily used than class variables, you will see accessors most often used with instance variables. Because they get and set variables, accessors are sometimes known as *getters* and *setters*, and when you write accessors, you will usually write both a getter and a setter. The convention is to name them the same as the instance variable. For example,

```java
Employee>>salary: aNumber
salary := aNumber
```

```java
Employee>>salary
^salary
```

If you choose to use lazy initialization (initializing a variable only when it is first needed) rather than to initialize instance variables in an `initialize` method, the `salary` accessor would look something like:

```java
Employee>>salary
^salary isNil
    ifTrue: [salary := 0]
    ifFalse: [salary]
```

Lazy initialization is a reasonable approach when variables are accessed infrequently or not at all, and the cost of initialization is high. Otherwise, it's probably worth initializing variables in an `initialize` method.

## Accessors for collections

If your variable contains a collection, what should the getter return? The usual answer is to return a *copy* of the collection. Other classes will be able to take actions based on the contents of the collection, but they won't be able to directly add to or remove from the collection. As well as providing accessors, you'd also provide methods to add to and remove from the collection. For example,

```java
Employee>>skills
^skillsCollection copy
```

```java
Employee>>addSkill: aSkill
^skillsCollection add: aSkill
```

```java
Employee>>removeSkill: aSkill
^skillsCollection remove: aSkill ifAbsent: [nil]
```

However, you might want to consider not providing *any* direct public interface to your collections. After all, you may decide to change the collection from an `OrderedCollection` to an `Array` or a `Dictionary` and you don't
want to be concerned about how other software is accessing the collection. By providing a few accessing methods such as the `addSkill:` and `removeSkill:` methods shown above, you don't have to expose the actual collection at all. (Another approach would be to provide a getter that always converts the actual collection into an `OrderedCollection` and returns this.)

## The five accessor approach

I have a friend who uses what he calls the "fascist" approach to instance variable accessors. For each instance variable, there are five accessors. Using a variable called `salary` as an example, we would have the following accessors in this scheme. The only two public accessors are `salary` and `salary:`. The others are all private. The public accessors are allowed to have side effects (for example, establishing connections), while the private methods are not allowed to have side effects<fnref n="2" />. Not many people use a technique this strict however.

```kotlin
Employee>>salary
    "Answer salary. This accessor is allowed to have side effects."
    self myGetSalary == nil
        ifTrue: [self mySetSalary: self myComputeSalary]
        ^self myGetSalary

Employee>>myGetSalary
    "Answer salary. No side effects are allowed."
    ^salary

Employee>>myComputeSalary
    "Answer the initial value for salary, possibly computing it"
    ^self baseSalaryForGrade * self locationFactor

Employee>> salary: aValue
    "Set the salary. This accessor is allowed to have side effects"
    self mySetSalary: aValue.
    self informPayrollSupervisor

Employee>>mySetSalary: aValue
    "Set the salary. No side effects are allowed"
    salary:= aValue
```

## Accessors or Direct Referencing

There are schools of thought about how instances should reference their instance variables. One school says that instance variables should *always* be referenced indirectly, through accessor methods. The other school says that *sometimes* instance variables should be referenced *directly*. Let's look at these two ideas.

```kotlin
ValueModel>>value: newValue
    "Set the currently stored value, and notify dependents."
    self setValue: newValue.
    self changed: #value

ValueHolder>>setParameter: aValue
    "Just initialize the value without notifying dependents of a change."
    value := aValue
```

<footnote n="2">² Jumping well ahead of ourselves, subclasses of `ValueModel` provide two setters, `value:` and `setValue:`. This allows objects to use `value:` when they want to notify dependents of changes, and `setValue:` when they want to make a change without notifying dependents. This latter option helps avoid infinite loops when updating a value as a result of a change notification from a dependent. Don't worry if this doesn't make any sense now—we'll cover dependencies later. Below are examples of both methods.</footnote>
## Direct referencing

The advantages of referencing instance variables directly are threefold. First, you don't have to write accessor methods (although the VisualWorks CodingAssistant helps you with this). Second, it's a little more efficient to access them directly because you save a message send on each access (although not much, since the compiler can optimize these message sends). The most significant advantage of referencing variables directly, however, is that you preserve the encapsulation of the object. Any time you write an accessor, the whole world has access to the instance variables, which violates the principle of encapsulation. Sometimes you want to give access to instance variables, but much of the time you'd like to keep private the internal details of how the class works. In *Celebrating 25 Years of Smalltalk*, Ward Cunningham says: "But if I could change anything...I'd like to see people stop giving away all their instance variables with accessing methods."

## Referencing through accessors

Requiring all access to go through accessors makes it easier to preserve the public interface to an object when the underlying implementation changes. You may get rid of instance variables or combine them in some way, but as long as you can compute the information that was returned by a getter, and as long as you can make use of the information that was given to a setter, you can preserve the same interface to the world. To use a trivial example, suppose we have an Account object which contains a *balance* instance variable. Perhaps the accessors at one time were:

```
Account>>balance: aFloat
    balance := aFloat

Account>> balance
    ^balance
```

We decide that we'd rather store the value internally in cents rather than in dollars, so we modify the accessors to look like:

```
Account>>balance: aFloat
    balance := (aFloat * 100) rounded

Account>> balance
    ^balance / 100
```

Other advantages to accessors include: If you want to change an instance variable, and instance variables are accessed directly, you have to look through the class and all its subclasses to find references to the variable; on the other hand, if you have accessors on all your instance variables, all you have to do is browse senders of the accessor messages. If you have long methods, it can be difficult to tell what are instance variables and what are temporary variables if you don't use accessors. Having set accessors makes it easier to notify dependents of changes, and to mark an object as modified or dirty when it has changed. For example, combining these last two, you might have a setter that looks like:

```
MyClass>>weight: aNumber
    oldWeight := weight.
    weight := aNumber.
    self markDirty.
    self changed: #weight with: oldWeight
```
## Which way to go

My view is that when implementations change, it's usually easier to find and change the references to variables than to preserve an obsolete interface. In code I write for myself, I tend to use accessors only when I want to provide public access to the variables — sometimes this means providing a getter but not a setter. At work, I follow whatever standards prevail (which is usually to use accessors for all instance variables) because I believe it's more important to conform to the standard than be inconsistent.

If you choose to use accessors, but are concerned about violating encapsulation, you can use the `my` prefix described in Chapter 3, Methods. This allows you to use accessors and also preserve the encapsulation, assuming that people don't violate the rules about methods starting with `my`. In Chapter 29, Meta-Programming, we will show an extension to *Class* that automatically creates both public and private accessors for all our instance variables when we define a class.

## Chains of accessors

One thing to beware of when writing accessors is creating long chains of accessors to get hold of an object in an object in an object in an object. For example, we might have something like:

```perl
companyName := employee department division company companyName.
```

The problem with this approach is that it violates encapsulation in a big way. Not only do you know the implementation details of the employee, but you also know and rely on the instance variables for the department, the division, and the company. This makes the system much more fragile because you can't make a change to any of the objects without worrying about how it will affect code. Instead, it's better to encapsulate the inner details. Provide accessors on the outer object that will return inner details. In our example, we might write `company` and `companyName` accessors on the employee, so we can now write:

```perl
companyName := employee companyName.
```

This means that we can restructure how the company is organized, perhaps removing the `division` layer, or perhaps adding a `country` layer, without having to change the code that needs the company name for the employee. Similarly, we would probably write `company` and `companyName` methods on *Department* and on *Division* for the same reason. Our accessors on *Employee* might look like the following.

```perl
Employee>>companyName
^self company companyName
```

```perl
Employee>>company
^self department company
```

This leads to the idea that to maintain loose coupling between classes, a method should send messages only to `self`, `super`, to its class, to instance or class variables, to a parameter, or to an object it creates. If the method sends messages to any other object it is either referencing a global variable, or it knows something about the internal details of the object. This is illustrated in Figure 4-3.
<table><tr><td>self</td></tr><tr><td>super</td></tr><tr><td>self class</td></tr><tr><td>self instVar</td></tr><tr><td>self classVar</td></tr><tr><td>aParameter</td></tr><tr><td>SomeClass new</td></tr></table>

someMethod: aParameter
self foo.
super foo.
self class foo.
self instVarOne foo.
instVarTwo foo.
self classVarOne foo.
classVarTwo foo.
aParameter foo.
thing := MyThing new.
thing foo.

<caption>**Figure 4-2.** Message sends for loose coupling.</caption>

## Documentation on variables

All instance, class, and class instance variables should be documented in the class comments. You should describe at least the type of the variable, its purpose, and any special information that will be useful to other programmers. For example, here is part of the class comment for Date.

Instance Variables:
day <Integer> from 1 to (365 | 366)
year <Integer> typically after the year 1900

Class Variables:
DaysInMonth <Array of: Integer> the number of days in each month
MonthNames <Array of: Symbol> the names of the 12 months

Once you have decided what information your project requires to be in a class comment, you can customize the class comment template by modifying the `commentTemplateString` method in `ClassDescription`.
# 5

## Instance Creation

We've now covered enough material to look more closely at creating instances of a class. The basic instance creation message is `new`, which returns a new instance of the class. For example,

```
employee := Employee new.
collection := OrderedCollection new.
```

If you send `new` to a collection class, it will return a new collection¹. The size will always be zero since the collection is empty, but the capacity will be the default capacity for that class. The capacity is the number of items you can put in the collection before it has to grow. For example, printing the following expressions gives the capacity shown on the right.

<table><tr><td><code>Array new capacity.</code></td><td>0</td></tr><tr><td><code>Bag new capacity.</code></td><td>0</td></tr><tr><td><code>Dictionary new capacity.</code></td><td>3</td></tr><tr><td><code>Set new capacity.</code></td><td>3</td></tr><tr><td><code>List new capacity.</code></td><td>5</td></tr><tr><td><code>OrderedCollection new capacity.</code></td><td>5</td></tr></table>

Growing a collection is quite expensive because the growing code creates a new collection with a larger capacity, copies over all the elements of the collection, then becomes the new collection. If you know how big the collection should be, or have an idea for the starting capacity, it's more efficient to create the collection by sending the message `new`: with the starting capacity as a parameter. Some collections, such as instances of `Array`, don't grow automatically, so it's important to specify their capacity (for collections that don't automatically grow, the size and capacity are the same). For example,

```
array := Array new: 10.
collection := OrderedCollection new: 20.
stream := (String new: 100) writeStream.
```

The `new` and `new:` methods are implemented by `Behavior`, although they are overridden by many other classes. Because your class will inherit `new` and `new:` , you don't need to override them unless your class has
data that needs to be set when an instance is created. There are two types of data setting that can be done: setting variables to a default initialized value, and setting variables to data that is specific to the instance. Let's take a look at each of these.

## Setting default values

Suppose we have an *Employee* object that tracks the number of hours of vacation and sick time allowed and taken. When an instance of *Employee* is created, we want to initialize these instance variables to the appropriate values, regardless of the name or salary of the employee. There are two ways of doing this. We can use lazy initialization as we saw in Chapter 4, Variables. For example,

``` employee>>sickHoursUsed ^sickHoursUsed isNil ifTrue: [sickHoursUsed := 0] ifFalse: [sickHoursUsed]
```

Alternatively, we could initialize all the data in a single *initialize* method. Lazy initialization is useful if you have objects where the data may never be accessed and where it's expensive to initialize the data, but it has a cost of an extra message send each time the data is accessed. If you will be accessing the data a lot, it's worth doing the initialization in an *initialize* method. For example, for our *Employee* object we might have the following (although we wouldn't have hard coded values for the *allowed* variables).

``` employee>>initialize self sickHoursUsed: 0. self vacationHoursUsed: 0. self sickHoursAllowed: 80. self vacationHoursAllowed: 80.
```

To invoke the *initialize* method you'll have to override *new* since the inherited *new* doesn't invoke *initialize* (at least if *Employee* is subclassed off *Object*). The usual way to override *new* is as follows (one of the most common errors of beginning Smalltalk programmers is to leave off the ^, which means that the class itself will be returned, rather than the newly created instance).

``` employee class>>new ^super new initialize
```

Before you override *new* like this, you need to be aware of what *super new* does. If the *new* method in the superclass sends *initialize*, your *initialize* method will be invoked twice, first by the superclass *new* method, then by the *Employee* *new* method. In this situation you don't need to override *new* since you can inherit it from your superclass. Since the superclass has an *initialize* method that presumably initializes superclass data, your *initialize* method should start with *super initialize*. For example, suppose we have an *Employee* class, with subclasses of *HourlyEmployee* and *SalariedEmployee*. Let's assume that hourly employees get two weeks of vacation while salaried employees get three weeks. We might have the following:

``` employee class>>new ^super new initialize
```

<footnote n="1">¹ Sending *new*: to a class that is not variable sized will generate an exception.</footnote>
Employee>>initialize
    self sickHoursUsed: 0.
    self vacationHoursUsed: 0.

HourlyEmployee>>initialize
    super initialize.
    self sickHoursAllowed: 80.
    self vacationHoursAllowed: 80.

SalariedEmployee>>initialize
    super initialize.
    self sickHoursAllowed: 120.
    self vacationHoursAllowed: 120.

While overriding `new` to be `^super new initialize` is the common way of doing it, some people prefer to use the `basicNew` message.

MyClass class>>new
    ^self basicNew initialize

Methods that start with `basic`, such as `basicNew` and `basicAt:`, should not be overridden. Their purpose is to provide the basic functionality, and programmers should be able to rely on this. If you want to override the functionality, override `new` and `at:`. By using `basicNew`, you don't have to worry about any superclass sending `initialize` and thus causing your `initialize` method to be invoked more than once. However, you still need to determine whether you should send `super initialize` in your `initialize` method.

## Overriding new

It gets frustrating to have to override `new` just so you can invoke `initialize`. One solution is to have all your application classes subclassed of `MyApplicationObject`, which is subclassed off `Object`. In `MyApplicationObject`, you override `new` on the class side, and write a default `initialize` on the instance side. Now you can override `initialize` in your class without having to override `new`.

MyApplicationObject class>>new
    ^self basicNew initialize

MyApplicationObject >>initialize
    "do nothing"

## Setting instance specific values

Often when you create a new instance you want to give it some information. In our employee example, we need at least a name. We may also need to provide a social security number, a salary, and information about gender, marital status, and number of dependents. There are two choices: to create the instance then set the variables, and to set the variables as part of instance creation. For the sake of example, let's assume that when creating an employee object, two pieces of information are absolutely required: a name and a social security number. If we create the instance then set the variables, we might have something like:

employee := Employee new.
employee name: aName.
employee socialSecurityNo: aSocialSecurityNo.

The problem with this approach is that you are relying on all programmers to remember to set the required variables after creating the instance. This is okay if the variables are optional, but dangerous if they are required. If you need to guarantee that the data is set, you are better off writing an instance creation method that forces programmers to provide the required information. For example, if we write our own instance creation method, we can create an employee like this:

employee := Employee name: aName socialSecurityNo: aSocialSecurityNo.

What would the `name:socialSecurityNo:` method look like? One option would be to simply pass on to an initialization method the information that needs to be set.

Employee class>>name: aName socialSecurityNo: aSocialSecurityNo
^super new initializeName: aName socialSecurityNo:
aSocialSecurityNo

This is a reasonable approach if you need an initialization method to initialize other data, such as the `vacationHoursUsed` variable shown above. However, if the initialization method does nothing except set the variables passed in, you might set the data directly. For example, you could use one of the following techniques; the second one dispenses with the temporary variable.

Employee class>>name: aName socialSecurityNo: aSocialSecurityNo
| instance |
instance := super new.
instance name: aName.
instance socialSecurityNo: aSocialSecurityNo.
^instance

Employee class>>name: aName socialSecurityNo: aSocialSecurityNo
^super new
name: aName;
socialSecurityNo: aSocialSecurityNo;
yourself

## Overriding new to avoid it being used

If you require programmers to use `name:socialSecurityNo:` to create instances of *Employee*, you could override `new` to raise an exception. Doing this is not very common, but it does make it easier for programmers to discover that they are creating employee objects in the wrong way.

Employee class>>new
self error: 'Please use name:socialSecurityNo: to create Employee
instances'

## Avoiding the use of new:

If only the employee name is required, you might be tempted to use `new: aName`. Resist the temptation. The instance creation message `new:` is used to specify the size of a collection, and programmers reading code should be able to assume that a collection is being created when they see `new:`. Instead, use `name:` or `newNamed:` or `newWithName:`. I tend to like method names that tell me both that they are creating a new instance and what the parameter is.
## Sole instances of a class

Some classes have but a single instance. Examples in the system classes are `true`, which is the sole instance of `True`, `false`, which is the sole instance of `False`, `nil`, which is the sole instance of `UndefinedObject`, and `Processor`, which is the sole instance of `ProcessorScheduler`. The classes `UndefinedObject`, `Boolean`, and `ProcessorScheduler` override `new` to prevent new instances being created.

In your own code, if you have a class that should have only one instance, the easiest way to handle this is to have a class variable that contains the sole instance. When someone tries to create a new instance after the first one, you can either raise an error or return the sole instance. For example,

```kotlin
MyClass class>>new
    Instance isNil ifFalse: [self error: 'You can only have one
instance of MyClass'].
    Instance := self basicNew.
    ^Instance
```

```kotlin
MyClass class>>new
    ^Instance isNil
        ifTrue: [Instance := self basicNew]
        ifFalse: [Instance]
```
# 6

## Special Variables, Characters, and Symbols

Smalltalk is a very small language, with a very large class library. But even though it is a small language, there are still a few things to learn.

### Character Pairs

There are several character pairs that mean things when used together. The VisualWorks Browser makes it easy to manipulate text and character pairs. You can surround a block of text with a character pair by highlighting the text then pressing *Esc-leftCharacter* (the Escape key followed by the left character of the pair). You can select and highlight all the text between a character pair by double-clicking between the character and the text (at either end). You can remove the character pair by highlighting the text between the pair then pressing *Esc-leftCharacter*.

### "This is a comment"

Text between pairs of double quotes is comment text and will not be compiled. You can make a block of text into a comment by highlighting it then pressing *Esc-*.

### 'This is a string'

Enclosing a sequence of characters within single quotes is a way to create an instance of String. See the section below on Automatically Constructed Objects.

### (2 * 3)

Enclosing something within parentheses gives it higher precedence. Thus, `1 + (2 * 3)` means that `2 * 3` is evaluated before adding the result to 1. Parentheses are also used to enclose literal arrays (see below).
The assignment operator is usually called 'gets' or 'colon equals' when speaking. Giving it a special name rather than 'equals' means that you are less likely to type something like `number = 3`, which sends the = message to number with 3 as the parameter, and returns a Boolean.

Note that you can do multiple assignments in a statement, although I don't particularly recommend it since it doesn't help clarity. For example,

`x := y := 3.`

## Return

The caret symbol (`^`) is the return symbol. If the line being executed says `^3`, the method will exit and return a `SmallInteger` with the value 3. `^` is the very last thing done in the statement. In the following example, the variable `instVar` will be assigned the value -3, then the value of `instVar` (ie, -3) will be returned from the method.

`^instVar := 3.14 truncated negated`

By default, a method returns `self`. That is, if the method gets to the end without executing an explicit `^` statement, it returns `self`. You can see this by holding down the Shift key when you select the method with the mouse. This shows the decompiled code, which will usually have `^self` at the end.

You will sometimes see fairly complex looking return values. Two common return statements follow. In the first example, you might think of returning from the blocks or setting a temporary variable, but the example shows the more common style. In the second example, we return the results of building a new collection in one operation rather than putting the new collection in a temporary variable then returning the temporary.

`^objectOne > objectTwo
ifTrue: [objectOne]
ifFalse: [objectTwo]`

`^someCollection
collect: [ :each | self manipulate: each]`

## Statement Separator

A period (`.`) is the statement separator. If there are two statements, the first needs a period to let the compiler know that the first statement is done and the second statement is about to start. Leaving out periods is one of the most common errors and usually results in a `messageNotUnderstood` exception when Smalltalk treats the first word of the second statement as a message to be sent to the result of the first statement. A good way to check for missing statement separators is to run the formatter after accepting a method. If the method looks different than you expected, you may have a missing period.

Note that the period is *not* a statement terminator. A method with one statement does not need a period. Nor is a period needed for the last statement in a method or a block. This is unlike C++ where a semicolon is a statement terminator and is required for all statements. Putting in a period after a statement where it is not needed is okay though. My usual mode of typing is to not worry about extra periods. After I'm done and the method compiles (ie, it is successfully accepted), I run the formatter, which removes any unnecessary parentheses and periods.
## Cascading

The cascade operator is a semicolon (;). Cascades allow you to send multiple messages to the same object (the same receiver) without having to name it every time. The most common occurrences are when printing to the Transcript, when overriding `printOn:`, and when adding multiple items to collections. For example,

Transcript cr; show: 'this is a string'.

aCollection
    add: 'this';
    add: 'that'.

printOn: aStream
    aStream
        print: self class;
        crtab;
        print: self instVarOne.

If you use cascades, the generally accepted practice is to put the message receiver on a line by itself, then each cascade goes on a separate line, tabbed over one from the receiver. Short messages such as `cr`, or `tab`, are often put on the same line in short cascades. Unfortunately the formatter destroys any indentation you specify for cascades. Because of this, I will often specify the message receiver each time and use a period to separate the statements. There is no performance loss by doing this.

## Automatically Constructed Objects

There are some objects that are created automatically rather than by explicitly sending a message such as `new` to a class.

### SmallInteger

4 An instance of SmallInteger can be created by simply using the integer value. One of the interesting things about integers is that you can't get integer overflow because if you add one to the largest possible SmallInteger, the return from the `+` message is a LargePositiveInteger. Try inspecting `SmallInteger maxVal + 1`.

### Float

3.14 An Instance of Float can be created by using a floating point value.

### String

'here is a string' An instance of String (actually a subclass of String) can be created by enclosing a sequence of characters in single quotes. String is a funny class because even if you do `String new` you still end up with an instance of a subclass of String. To create a string with an embedded quote, use two single quotes to denote the embedded quote. For example,

'You can''t do that'.
## Character

$A An instance of Character can be created by preceding the character with a dollar sign. For example, the character X is created by writing $X. You can create instances of space, tab, carriage return and other white-space characters the same way; for example, you can refer to a space as $ and a newline by typing $ followed by pressing the return key. However, it's difficult to read white space characters created like this, so the preferred way to create them is to send the appropriate message to Character (eg, Character space or Character cr). To see which characters can be created with message sends, look at the class side messages of Character or inspect Character constantNames.

## Symbol

#notFound An instance of Symbol can be created by prefixing a sequence of characters with a #. If you want the symbol to contain space characters, you can enclose the symbol name with single quotes. For example, #'not found'. If you inspect this symbol, it will display with the quotes but when you look at the first character, you will see that it is a $n rather than a single quote.

## Array

#(1.1 $a 'hi') An instance of Array can be created by enclosing other automatically constructed objects between parentheses and preceding this with a # character. Note the space between array elements. Note also that the array elements do not have to be of the same type.

You cannot use this type of construction with objects that require message sends. So you can't say #(1 (Character cr)) and expect to get an array of an Integer and a Character. However, you can create literal arrays that contain other literal arrays, such as #(1 $a #(1.1 'hi' #2 #symbol)).

## BlockClosure

['Hi' echo] An instance of BlockClosure can be created by enclosing code between square brackets. The code will not be executed until the block is send a message from the value family. You can set up code in a BlockClosure then pass the block to another method where it will be executed. BlockClosures are often stored in Dictionaries for later access and execution. Note that the value of a block is the value of the last statement evaluated in the block. So, the value of [ 3. 4. 5. 1 ] is 1.

Blocks can have parameters, which are defined with a colon in front of them and a vertical bar separating them from the rest of the block. For example [ :parameter | parameter echo ]. Blocks can also have temporary variables, which are enclosed between vertical bars. For example, [ :parameter | | temp | temp := parameter * 2. temp echo ].

If all the blocks used as either receivers or parameters in messages such whileTrue:, ifTrue:, and and: are literal blocks (i.e., defined directly with square brackets and not stored in a variable), the blocks will be compiled in-line and are not treated as blocks.

There are three kinds of BlockClosures: full, copying, and clean. In general, blocks need to maintain a reference to the method that defined them, which they store in a variable called outerScope. If the block contains an explicit return (^), or a reference to variables defined outside the block and which can change after the block
is created, outerScope will contain a non-nil value and the block is a *full block*. If there is no explicit return and any outside variables are determined to be non-changing after the block is created, copies of these variables are made and stored in another instance variable called *copiedValues*. For obvious reasons, this type of block is called a *copying block*. A block that contains neither an explicit return or references to outside variables is called a *clean block*. So, for example:

<table><tr><td>[ :parameter | parameter echo ]</td><td>clean</td></tr><tr><td>[ :parameter | | temp | temp := parameter ]</td><td>clean</td></tr><tr><td>[ :parameter | self foo: parameter ]</td><td>copying (note the self)</td></tr><tr><td>[ methodTemporary echo ]</td><td>copying or full</td></tr><tr><td>[ :parameter | ^ parameter * 3 ]</td><td>full</td></tr></table>

Because full blocks have to chain back through the outer scope pointers, and this chaining is relatively expensive, it pays to avoid full blocks if possible. Create clean blocks if you can since they have the highest performance. If your block refers to *self* or to another outside variable, try to make it a copying block — ie, convince the compiler that the variables will not change after the block is created.

## = and ==

The two messages `=` and `==` are not special in the same way as the things described above; they are just binary messages like any other binary message. However, there are some things about them that deserve to be specifically mentioned, so here is as good a place as any.

The `=` message returns *true* if the two objects are equal, while the `==` message returns *true* if the two objects are *identically equal*. What does this mean? (The opposites of `=` and `==` are `~` and `~~`. These are a single tilde and two tildes.)

### Identically equal

Objects are *identically equal* when they are the *exact same* object. The way that Smalltalk knows they are the same object is that they have the same object pointer. Object pointers are 32 bit quantities, with some of the bits providing information about whether the value is a pointer or an object value. If you have an employee object, the object pointer will reference the employee object that exists somewhere in memory. Two employee objects are identically equal if the object pointer references the same location in memory.

On the other hand, some objects can be represented fully in 32 bits. These objects return *true* when sent this `isImmediate` message, and currently are objects of class *SmallInteger* and *Character*. (The maximum value of *SmallInteger* is less than the maximum value of a 32 bit integer because three bits are used to denote that it is a *SmallInteger* and not a pointer to an object.) Because of the way they are stored, identically named instances of *Symbol* are also identically equal.

<table><tr><td>3 == 3</td><td>true</td></tr><tr><td>$a == $a</td><td>true</td></tr><tr><td>#abc == #abc</td><td>true</td></tr><tr><td>true == true</td><td>true</td></tr><tr><td>nil == nil</td><td>true</td></tr><tr><td>'abc' == 'abc'</td><td>false</td></tr><tr><td>3.14 == 3.14</td><td>false</td></tr><tr><td>#(1 $a) == #(1 $a)</td><td>false</td></tr></table>
If you examine the following, you will discover that x is identically equal to y. This is because assignment
does not copy the value; it binds the same object to a new variable so that both variables now contain the same
object.

x := # (1 $a) .
y := x.
x == y true

Equal

Objects are equal when their values are equal. Two strings with the same character sequence will be equal. If we look at the examples above that returned false and check for simply equality, we get

'abc' = 'abc' true
3.14 = 3.14 true
#(1 $a) = #(1 $a) true

If you define a new class, how does the default = method tell whether you consider two objects of this class to be equal? The answer is that it doesn't. If you look at the default = method defined by Object you will see that the default implementation requires two objects to be identically equal before it agrees they are equal. Ie, = simply does ^self == anObject.

If you define your own = method you should also write a hash method, and vice versa. Two equal objects
should also have the same hash value. The reason that hash and = need to go hand in hand is that some
collections store objects using a hashing scheme (such as Dictionary, Set, and Bag). Because hashing schemes
can have location conflicts, a hash scheme uses hash to find the primary location for the object, then uses = to
see if an object in the location is the object it wants. (By the way, don't try to redefine ==. First, the system will
ignore your override, and second, == has a well-defined meaning that should not be changed.)

If you override =, you might consider first checking that the class of the receiver is the same as the class of
the parameter. The first example below checks that the classes are the same, while the second allows the
parameter to belong to a subclass of the receiver.

MyClass>> =
anObject class == self class ifFalse: [^false].
...
MyClass>> =
(anObject isKindOf: self class) ifFalse: [^false].
...
7

Global Variables

I'll start with the standard caveat that global variables should be used sparingly, if at all, and that most
information should be stored in instance variables or be passed as method arguments. Having said that, there is a
definite use for global information and objects. You may have constants that are used through your system, or
you may have global objects such as configuration objects or trace log objects. Let's look at some techniques that
can be used for these purposes. We'll use two examples: a configuration object and a timeout value.

Global Dictionary

The most basic technique is to put global objects in the system dictionary named *Smalltalk* since objects in *Smalltalk* can be referenced from anywhere. For example, you might have code that does:

Smalltalk at: #Timeout put: 20.
Smalltalk at: #Config put: MyConfiguration new.

I recommend against using *Smalltalk* for application globals because it's used heavily by the Smalltalk system (for example, it contains all the classes in the system, and global variables such as *Transcript*, *Processor*, and *ScheduledControllers*). I prefer not to clutter *Smalltalk* up with application objects or risk name collisions.

Pool Dictionaries

The next technique is to use a *PoolDictionary*. A PoolDictionary contains objects to which you want global access for your application. The nice thing about a PoolDictionary is that classes have to register an interest in it before they can access its objects, so it allows you a certain amount of scoping. The way a class registers an interest is to name the PoolDictionary in the appropriate line in the class definition template. (In VisualWorks 2.0, subclasses inherit the PoolDictionary, but in VisualWorks 2.5, you have to explicitly name the PoolDictionary in each subclass that wants to reference PoolDictionary variables.) In the example below, I've called it MyPoolDictionary.

NameOfSuperclass subclass: #NameOfClass
instanceVariableNames: 'instVarName1 instVarName2'

Copyright © 1997 by Alec Sharp

Download more free Smalltalk-Books at:

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

- European Smalltalk Users Group: http://www.esug.org
classVariableNames: 'ClassVarName1 ClassVarName2'
poolDictionaries: 'MyPoolDictionary'
category: 'MyStuff'

Before you write code you must have done two things. First, before referencing the `PoolDictionary` in your class definition you have to make the name of the `PoolDictionary` universally known by adding it to the `Smalltalk` dictionary. To do this, execute the following. Note that we are using a `Dictionary` and not an `IdentityDictionary`. Because of the way an `IdentityDictionary` is implemented, it will not work as a `PoolDictionary`.

Smalltalk at: #MyPoolDictionary put: Dictionary new.

Before you write code referencing the objects in the `PoolDictionary`, you have to add these objects to the `PoolDictionary` so that the compiler can associate a variable name in your method with an object in the `PoolDictionary`. However, the compiler just needs to be able to reference the name in the `PoolDictionary` and doesn't care about the type of the object. For the purpose of accepting your method, the easiest thing to say initially is:

MyPoolDictionary at: #Config put: nil.

We don't want to do these steps manually every time we file in our code (see Chapter 33, Managing Source Code, for more information on managing projects and filing in code). So, at the beginning of the file that files in our code, we add the following.

Smalltalk at: #MyPoolDictionary put: Dictionary new.
MyPoolDictionary at: #Config put: nil.

If you have code that refers to `PoolDictionary` variables and you create a new `PoolDictionary`, the code will no longer be able to find the old variables. If you get an error in a method because a `PoolDictionary` variable is not found, and yet a `PoolDictionary` exists with the appropriate variable, recompile the method by making a small change and accepting the method. If this solves the problem, somewhere you created a new `PoolDictionary` while code still references the old one.

The question that always comes up when using a `PoolDictionary` is how do you find all the references to an object in your `PoolDictionary`, since you can't browse References To or Implementors Of? The answer is to evaluate the following code:

Browser browseAllCallsOn: (MyPoolDictionary associationAt: #Config).

It might be worth putting something like this in your Workspace and saving your image. VisualWorks 1.0 had a menu option to open the System Workspace which, among other useful code samples, had code to find `PoolDictionary` variable references. The System Workspace is not obviously available in VisualWorks 2.0 or 2.5, but you can get it by executing:

ComposedTextView openSystemWorkspace.

Advantages of using a `PoolDictionary` are: you refer to the objects in a `PoolDictionary` by a name starting with an uppercase letter, which makes it very obvious that the code references a global object; and, only classes with an interest in the `PoolDictionary` have access to it. Disadvantages of `PoolDictionaries` are: you have to take
specific actions to allow `PoolDictionary` objects to be referenced, and it is harder to find all the references to the `PoolDictionary` object.

## Class side variables

The next technique is to use a class to store global data. For example, we might have two classes: `MyGlobs` and `MyConstants`. Global and constant values are referenced by sending messages to the appropriate class. For example, we might reference and define a timeout value as follows.

```
MyClass>>myMethod
    timeout := MyConstants timeout.
    ...

MyConstants class>>timeout
    ^20
```

We might reference and initialize a global value (in this case a Log file) as follows.

```
MyClass>>myMethod
    ...
    MyGlobs logfile log: 'salary=', salary printString.

MyGlobs class>>logFile
    ^LogFile

MyGlobs class>>initialize
    LogFile := MyLogFile on: self logFileName.
```

To find all references to an individual global, we can browse references to the message that returns the global. To see all the places that any global is used, we can browse class references for `MyGlobs`. Similarly, for constant values.

Unlike with variables in a `PoolDictionary`, we don't have to do anything special on `fileIn`, and we don't have to make sure that the reference contains an object when we write methods that refer to constants and globals. The only disadvantages of this approach over a `PoolDictionary` are that you can't restrict scope in the same way, and you have a class that does not act as a factory for instances.

## Default instances

There's one other thing to talk about since we are on the topic of class side behavior. Sometimes you have a single instance of a class that you want to access from many places. Our Configuration object may be such an example. There's a definite temptation to say that there will never be more than one instance of this class, so we might as well just dispense with the instance and put all the information and behavior on the class side. That way you can access the behavior easily since class names are globally known.

Despite the temptation, it should be resisted. There's another way that allows similar ease of access without preventing you from creating additional instances. Suppose the class is `MyClass`. Define a class variable called
*Default*. On the class side, create a *class initialization* protocol with an *initialize* method <fnref n="1" />. In the class side *initialize* method do the following:

```swift
MyClass class>>initialize
"self initialize"
Default := self new.
```

You'll probably need to initialize the instance so you'll either need to write `new`, which invokes *initialize*, or in the class *initialize* method do `Default := self new initialize`. Then on the class side write a *default* method:

```swift
MyClass class>>default
^Default
```

In your application code, you can now write code such as:

```swift
length := MyClass default length.
```

If you want to get *really* fancy, you can assume that instance side messages being sent to the class are really intended for the default instance. You'd write the last example as:

```swift
length := MyClass length.
```

Given that the class doesn't understand the `length` message, how do we make this work? We can implement `length` on the class side as `^self default length`, or we can implement the method `doesNotUnderstand:` on the class side as follows.

```swift
MyClass class>>doesNotUnderstand: aMessage
^self default
perform: aMessage selector
withArguments: aMessage arguments
```

I don't particularly recommend this way of coding because it's not obvious how it's working, but hey, it's ideas like this that make Smalltalk so much fun. If you decide to use this technique, make sure your class comments contain explicit information about what you are doing.

## Environment Variables / Command Line Arguments

Environment variables and command line arguments are not global variables, but since the information is globally available, and varies depending on the environment and how the image was invoked, we'll mention them here. The following returns an array containing the command line arguments. The first element is the program name and the second is the image name. Any additional array elements will be other command line arguments you added.

```c
CEnvironment commandLine.
```

<footnote n="1">¹ Class initialization is only done on fileIn so it's a good idea to always put `self initialize` in comments at the start of class side *initialize* methods. That way you can reinitialize the class if you make changes to *initialize*. Of course, you can select the whole method and *doIt*, but having `self initialize` makes it more obvious that it may need to be done.</footnote>
You can also retrieve environment variables using `getenv`. For example,

```
CEnvironment getenv: 'LOGNAME'
```

## Image Version Number

The version number for your image can be discovered in one of two ways. You can send the `version` message to Smalltalk, or the `versionId` message to ObjectMemory. For example, on a VW 2.0 system, I get the following.

```
Smalltalk version      'VisualWorks(R) Release 2.0 of 4 August 1994'
ObjectMemory versionId #[42 26 35 0 20 0 0 4 42 26 35 4].
```

In particular, element 5 of the array returned by `versionId` is the image major version number. VW 2.0 gives 20, while VW 2.5 gives 25. So, to discover if you are using VW 2.0 you could do either of the following.

```
(Smalltalk version findString: '2.0' startingAt: 1) > 0
(ObjectMemory versionId at: 5) == 20
```
8

Control Structures

Modern programming languages provide ways to execute code conditionally and to repeat blocks of code. In C, we have `if () {}`, `if () {} else {}`, `do {} while ()`, `while () {}`, and `for (;;) {}`. These types of construct are usually part of the language.

In Smalltalk however, the language itself does not have any of these constructs. Instead, they are created by sending messages to objects. The result of this is that if you don't like the way a control message works, you can change it (not recommended!). If you want a new type of control structure, you can write it. For example, Smalltalk does not come with a switch/case message, so if you feel the need for one, you can write it (again, not recommended for reasons we'll see in Chapter 28, Eliminating Procedural Code). In fact, you probably won't need any control structures other than those that come standard with the Smalltalk library. Let's go through these.

Conditional Execution

The simplest type of conditional execution is to only execute a particular block of code if some condition is true (or false). In Smalltalk, there are two messages, one for when the condition is true and one for when it's false. Both messages are sent to an instance of *Boolean* (ie, to *true* or *false*). Here is the general approach, with an example.

```
booleanValue ifTrue: [some code].
booleanValue ifFalse: [some code].
3 < 4 ifTrue: [Transcript cr; show: 'True']
```

We can extend this to executing some code if the condition is true and other code if the condition is false. In Smalltalk we write one of the following. The `ifTrue:` and `ifFalse:` blocks can be in either order. For example, if the `ifTrue:` block is long enough to obscure a later `ifFalse:` block, put the `ifFalse:` block first.

```
booleanValue
    ifTrue: [some code]
    ifFalse: [some code].
```
booleanValue
    ifFalse: [some code]
    ifTrue: [some code].

For example,

3 < 4
    ifTrue: [Transcript cr; show: 'True']
    ifFalse: [Transcript cr; show: 'False'].

Smalltalk doesn't provide an easy way to do C's `if () {} else if () {} else {}` type of construct. You can do it with nesting such as:

booleanValue
    ifTrue: [some code]
    ifFalse: [booleanValue2
        ifTrue: [some code]
        ifFalse: [booleanValue3
            ifTrue: [some code]
            ifFalse: [some code]]]

However, this type of code is very procedural rather than Object-Oriented. If you find that you are writing code like this, it may be time to rethink how you are doing things. See Chapter 28, Eliminating Procedural Code for more information.

## Looping

Smalltalk has no looping constructs in the language. Instead, it provides looping functionality by sending messages to BlockClosures. The most basic type of loop is one that continues to loop while some condition is true. As long as the block (ie, the last statement in the block) evaluates to *true*, the loop will continue. This type of mechanism is similar to C's `do {} while ( );` construct. Here are the syntax and an example.

[some code] whileTrue.

count := 0.
[Transcript cr; show: count printString.
count := count + 1.
count < 10] whileTrue.

The condition can be reversed so that the loop continues as long as the block evaluates to *false*.

[some code] whileFalse.

The next type of looping mechanism is similar to the above, but if the first block evaluates to *true*, a second block of code is executed. This type of mechanism is somewhat similar to C's `while () {}` but is more powerful because it allows multiple statements in the first block. Again, here are the syntax and an example.

[some code]
    whileTrue:
        [more code]

[Dialog confirm: 'Continue']
    whileTrue:
        [Transcript cr; show: 'Continuing'].
As before, you can reverse the conditions so that the loop continues if the first block evaluates to `false`.

```pascal
[some code]
whileFalse:
    [more code]
```

The final straight looping mechanism is one that simply repeats. This means that the code in the block needs a way to return from the method, or to somehow stop execution or you will find yourself in an infinite loop.

```pascal
[some code] repeat
    [(Dialog confirm: 'Continue') ifFalse: [^self].
     Transcript cr; show: 'Continuing'] repeat.
```

## Repetition

In Smalltalk, there are three ways to repeat a block of code a fixed number of times. Two of them pass in the index, while the other one assumes that you don't care which iteration you are on. If the loop doesn't care about the index number, the simplest mechanism is to send `timesRepeat`: passing the code block as the parameter. For example:

```pascal
5 timesRepeat: [Transcript cr; show: 'hello']
```

If the loop needs to know what iteration it is on, you'll need to send one of the following two messages. If you want to loop from one number to another, incrementing by one each time, send `to:do`: passing the code block as a parameter. The block expects to receive the index number as a parameter. For example,

```pascal
1 to: 5 do: [ :index | Transcript cr; show: index printString]
```

If you need a loop like this but don't want to increment by one, you can specify the step value by sending `to:by:do:`. Again, this message expects the block of code as a parameter, and the block should expect to receive the index number as a block parameter. For example,

```pascal
15 to: 1 by: -2 do: [ :index | Transcript cr; show: index printString].
```

Despite the existence of these messages, they are less useful than you might expect. Most repetitive looping is done over collections of objects, and collections have some powerful mechanisms for looping. We'll talk a lot more about looping over collections in Chapter 11, Collections.

## Optimized Messages

BlockClosures are used in the above control mechanisms usually as parameters, but sometimes as the receiver of the message. The BlockClosures can be stored in variables or can be written as literal blocks — ie, as code with square brackets around it.

If all the BlockClosures involved in the control message are literal blocks, the message is compiled in-line and so no message send occurs. On the other hand, if any of the BlockClosures involved in the message are
variables rather than literal blocks, the code will not be in-lined and the message will be sent. Usually these
messages are compiled in-line since most blocks are literal blocks.
9

Object-Oriented Thinking

Smalltalk is one of the pure Object-Oriented (OO) languages. Unlike C++, which makes it very easy to write procedural code (ie, use C++ as a better C), Smalltalk makes it difficult to write procedural code. Thinking in objects is very different from thinking in procedural terms and it usually takes about 8-12 months for experienced procedural programmers to become fairly automatic in their OO thinking. To use a language that doesn't help that process makes it much easier to remain in a half-way schizophrenic state.

OO thinking is fun and it is different. One difference is that OO development tends to be more iterative than procedural development, more spiral. In OO development we tend to acknowledge that we don't fully understand our objects and their interactions. Some objects that we thought we needed will disappear, others will come into existence as we realize we need them, while others will find their behavior and responsibilities changed or split off to other objects.

Little steps

Because Smalltalk code is so easy to change, it's very natural to approach problems in an iterative way. When I'm faced with a difficult application problem, I don't usually know how I'm going to solve it. I do enough analysis and design to get a grasp on the problem, but the whole solution rarely appears to me. So, I just start somewhere and write Smalltalk code. The act of writing the code, creating the classes and defining their interactions gives me new insight into the problem and into solutions. Which then allows me to write code to explore those new ideas, which leads to fresh insights, and so on.

Smalltalk makes it very easy to approach problems in an iterative manner, taking very small steps, getting things working, then taking the next small step. In working like this you really are combining the analysis, design, and programming phases, doing a bit of each, then a bit more of each. The OO cycle is very much one of do some analysis — do some design — do some programming — gain some insights — do some analysis, etc.
<figure><img src="image_11.png" /><figcaption>**Figure 9-1.** The object-oriented development cycle.</figcaption></figure>

## Write down the concepts

It is extremely easy to write, test, and change code in Smalltalk. This ease of writing allows you to write your design in the code, to think in conceptual terms rather than worrying about the details (which is exactly the difference between design and implementation). In a method, just write down the things that need to be done, at a fairly high conceptual level. Someone should be able to easily read the method to see what it's doing (short method, very descriptive names), without actually seeing any of the work being done. So, for example, you might write a method as follows.

```MyClass>>doSomething
self myDoConceptualThingOne.
self myDoConceptualThingTwo.
self myDoConceptualThingThree
```

You've now written down the basic design. You can implement the design by writing `myDoConceptualThingOne`, etc. The beauty of being able to do this easily is that as you gain insights into the domain problem, you can easily incorporate changes. For example, it might become apparent that another object should be doing `ConceptualThingTwo`. However, you also need to do `ConceptualThingFour`. It is very easy to move `myDoConceptualThingTwo` to another object then to modify your code.

```MyClass>>doSomethingWith: anObject
self myDoConceptualThingOne.
anObject doConceptualThingTwo.
self myDoConceptualThingThree.
self myDoConceptualThingFour
```

Admittedly, this is low level design; however, this is not a book on Design, so we won't explore how you work on the big-picture.

## Put off the work

Because good Smalltalk methods are small, it's hard to do much work in such a method. Which leads to the next Smalltalk OOP principle: put off the work as long as possible — make another method do it. The ease of writing Smalltalk code makes it possible to put off real work until later, so a lot of methods will do nothing but divide up the work. Eventually someone has to do the work, but if you consciously put off the work as long as you can, you will end up with a more object-oriented system.
Smalltalk might be considered the procrastination language — procrastinate as long as possible and maybe you won't need to do anything. When in doubt, put it off. Here's an example of poor code that we will try to refine using the principles just described.

```java
MyClass>>myDoLoop
    [object := self mySharedQueue next.
    object isHeartbeat
        ifTrue: [self myHeartbeat: object].
    object isSuccessResponse
        ifTrue: [self mySuccessResponse: object].
    object isFailureResponse
        ifTrue: [self myFailureResponse: object]
    ] repeat.
```

If we strip this down to the bare bones, we get something from a SharedQueue and process it, then repeat these actions. So we might write:

```java
MyClass>>myDoLoop
    [object := self mySharedQueue next.
    self myProcessObject: object ] repeat.
```

If we put off the decision on where to get the object, we might end up with:

```java
MyClass>>myDoLoop
    [self myProcessObject: self myObject] repeat
```

We now have a very generic loop, one that could be put in a superclass and inherited. It doesn't care where the input comes from or how we plan to process the object. In our case, `myGetInput` is very simple. It just does:

```java
MyClass>>myGetInput
    ^self mySharedQueue next.
```

In another problem domain it might be a lot more complex, getting input from the user, a socket, a file, a serial line, a UNIX pipe, etc.

(A side benefit of doing the processing in other methods is that you can't modify a running loop and have the changes take effect. Since the code is already running, the changes will be ignored until next time you run the loop. By putting the processing code in other methods, you can put debugging changes in them and have the changes take effect the next time the method is executed.)

## Tell, Don't Ask

What about `myProcessObject:` in the above section? We could certainly put our conditional code there — we would have moved it away from the main processing — but the code would still be very procedural. We need to rethink our objects so that we can simply ask the objects to process themselves. Procedural code gets information then makes decisions. Object-oriented code tells objects to do things.

```java
MyClass>>myProcessObject: anObject
    anObject processYourself
```
Another example might be displaying graphical objects in a window. If we were thinking procedurally, our Window object might have code that looks like

```kotlin
MyWindow->displayObject: aGraphicalObject
    aGraphicalObject isSquare ifTrue: [self myDisplaySquare:
        aGraphicalObject].
    aGraphicalObject isCircle ifTrue: [self myDisplayCircle:
        aGraphicalObject].
    aGraphicalObject isTriangle ifTrue: [self myDisplayTriangle:
        aGraphicalObject].
```

We are asking questions, getting back information, and executing code based on the information. If we were thinking more in OO terms, we would be trying to avoid getting information and making decisions. Instead, we'd be *telling* the object to do something. Our example might be transformed into

```kotlin
MyWindow->displayObject: aGraphicalObject
    aGraphicalObject displayYourselfOn: self
```

One benefit we get out of this transformation is that it becomes a lot easier to handle different types of graphical object. Rather than having to modify the window code every time we come across a new type of graphical object, we just need to make sure that each class of graphical object we write knows how to display itself. So if we add a Hexagon class, we just need to write `displayYourselfOn:` for the Hexagon (unless it can inherit from a superclass).

## Don't check the results of doing things

In a procedural system we typically make a function call, get back some status information about the results of the call, check the status information, and possibly do some error handling. In a Smalltalk OO system it's much more appropriate to just tell an object to do something, then forget about it. It's as if we are sending messages out into space, never to return.

Obviously we need to handle error situations in production quality code, but Smalltalk provides a special mechanism for that. Chapter 20, Error Handling, provides more information, but briefly, we can wrap a whole hierarchy of message sends in a signal handler. If an exception is raised because of some error, the exception bubbles up the stack until it finds a signal handler that can handle it. The signal handler then takes the necessary actions. The beauty of this scheme is that once we wrap our code in an exception handler, we can write it as though every message send is successful.

There will be some situations where it may be appropriate to get back a status object from a method, such as if we are requesting information from an external source. However, the majority of error handling can be done with exceptions rather than by checking status returns.

## Signs of Object-Oriented Thinking

### Short methods

The average Smalltalk method length is seven lines. I've always made it a rule that methods should fit into my browser window and I very seldom break that rule. If a method is too long, I'll try to find two or three
conceptual things that the method is doing, and create separate methods for each of them. If you consistently have methods that don't fit in a browser window, you are probably thinking procedurally. (The other value in having all methods fit within the window is that if you can see the whole thing, you can better grasp what is going on.)

## No dense black methods

Another indication that your methods are doing too much is when they look too black. This is an aesthetic judgment, but can be a useful heuristic to determine whether you are trying to do too much in a method. Try to make methods "stupid". A stupid method is one that is so simple that it's obvious what it's doing; it doesn't need to be documented. Black methods are usually the opposite of stupid methods, too much black being an indication that a lot is going on in the method.

## No super-intelligent objects

There is no rule for how many methods an object has, but there are some aesthetic judgments you can make. If you find that one object has many more methods than other objects, it may be that you are not distributing the workload well. In a good Object-Oriented system, you don't have super-intelligent objects. Instead, you have many peer-type objects cooperating. Super-intelligent objects often indicate that there is too much procedural thinking (in a sense a procedural system is one with a single super-intelligent object). It may be time to rethink your objects if you have classes with an uneven distribution of methods between them.

## No manager objects

It's very easy to write systems with manager objects telling other objects what to do. A good object-oriented system tends to have a lot of peers cooperating, with a reasonably equal distribution of responsibilities and workload. Managers tend to make a lot of decisions that other objects could be making. If you have a classes whose name ends in Manager, you might give some thought to how you could distribute the manager's workload to the objects it is managing.

## Objects with clear responsibilities

Each class should have a clear responsibility. If you can't state the purpose of a class in a single, clear sentence, then perhaps your class structure needs some thought.

## Not too many instance variables

If a class has a lot of instance variables, this can mean that it's trying to do too much, that you are not distributing the workload well. It may be possible to create other objects that can act in a supporting role or can collaborate with this objects of this class.

## Getting started with Object-Oriented Thinking

It can be difficult to start thinking in terms of objects if you've been programming in a procedural language for some time. One approach I've found very useful in learning Smalltalk and Object-Oriented techniques is to
work in pairs at a workstation. One keyboard, one screen, two people. One person types, while the other person makes suggestions, asks questions, and points out errors. After a while they change roles and the other person types. In this approach, you get the best of two people rather than the best of one person. Designs are better thought through because there's another person asking why and suggesting alternatives. Code has fewer bugs because there's someone else looking at the code. The code usually ends up being more efficient, maintainable, and consistent. Because there is a second person looking at all the code, there's much less need to review low-level designs and code.

Since two people work on all features, you now have two people who understand the code rather than just one. And both people learn from each other. Programmers have their own styles, techniques, and toolboxes of solutions. By working in pairs, they learn these things from each other and grow as programmers. By periodically change partners, these techniques and solutions are passed from person to person, with each person in effect learning from everyone their partner has previously worked with.

When I started programming in Smalltalk, I worked with another developer as a pair. It was great fun and we both learned a lot from each other. Since then I've always favored the pair approach, and so I read with interest two pieces that I later came across, both praising the concept of programming in pairs. In his article in the July/August 1995 issue of *The Smalltalk Report*, Kent Beck says "The most productive form of programming I know (functionality/person/hour) is to have two people working with one keyboard, mouse, and monitor." The second piece was a section called *Dynamic Duos* on page 118 of Larry Constantine's book *Constantine on Peopleware*. Constantine praises the two person concept, remarking that "The operating principle here is very broad: Increasing work visibility leads to increased quality!"
10

Object

Smalltalk is a *rooted* system, which means that there is a root superclass from which all other classes are descended. That root superclass is *Object*. (Actually, there other root classes, and you can see them by inspecting *Class rootsOfTheWorld*. However, for most application development you can consider *Object* to be the single root class.)

Object provides a lot of behavior that is inherited by all its subclasses, although sometimes they will override
that behavior. It's worth looking through all the protocols and methods of Object to become familiar with the
general behavior that is inherited by all classes. Let's take a look at some of the instance side protocols of Object.
We won't look at all protocols, or even all methods in the protocols we do look at, but we'll cover enough to give
you a feel for what your classes will be inheriting from Object.

Accessing

The message `at:` will give the object at the specified index, while `at:put:` puts an object at that index. The `size` message returns the number of indexable fields in the object. These messages only work with indexable objects; ie, collection type objects. Similar methods, `basicAt:`, `basicAt:put:`, and `basicSize` do the same things, but should never be overridden by subclasses. The intent is that you can always rely on the `basic` methods to provide the functionality without worrying that some intermediate superclass might have overridden them. Finally, `yourself` returns the receiver of the message. It is often used in cascades to make sure that the correct object is returned. For example, in `list := List new add: 1; yourself`, the `yourself` makes sure that the variable contains the list rather than the number one.

Changing

The message changed, changed:, and changed:with: are all used to set off dependency notification.
The typical use is that an object sends one of these messages to itself when it has changed, and all dependents of
the object are informed. We'll see more about the dependency mechanism in Chapter 19, The Dependency
Mechanism. The changeRequest message is sent when an application wants to change and is asking its
dependents if they agree to the change. Your application can override `changeRequest` to put in any
application specific checking.

## Class membership

The message `isMemberOf:` tells if the receiver is an instance of the specified class, `isKindOf:` tells if the receiver is an instance of the specified class or one of its subclasses, and `respondsTo:` tells if the receiver understands the specified message. The use of all three methods often indicates that you are thinking in procedural terms, that you are not using polymorphism well. These three methods should generally be avoided. The message `class` gives you the class of which the receiver is an instance.

## Comparing

The message `==` tells you if the receiver and parameter are the same object, if they are identically equal. The message `=` tells you if the receiver and parameter are equal. For example, two strings with the same characters are not the same object, but they are equal, so `==` returns *false* and `=` returns *true*. Since different classes have different criteria for judging their instances to be equal (for example, two `Employee` objects may be equal when the social security numbers are the same), the default implementation of `=` is simply to invoke `==`, leaving subclasses to override `=` with more appropriate behavior. (You should never override `==`.) Corresponding to `=` and `==` are `=~` and `~~`, which are not equal and identically not equal. The message `hash` returns a hash value for an object, and should be overridden whenever you override `=` because two objects that are equal should have the same hash value. For more information on all this, see Chapter 6, Special Variables, Characters, and Symbols.

## Converting

The message `->` returns an Association with the receiver as the key and the parameter as the value. Associations are useful when you want a pair of objects, and they are used in Dictionaries, which hold all the key-value pairs in Associations. The message `asValue` puts the receiver in a `ValueHolder` and returns this. `ValueHolders` are widely used by the user interface dependency mechanism, which wants a level of indirection when referring to an object.

## Copying

The `copy` message copies the receiver. It is implemented by sending `shallowCopy` then `postCopy`. The `shallowCopy` method makes a *shallow* copy of the receiver — ie, it doesn't make copies of any of the instance variables, leaving both the original object and its copy sharing instance variables. The message `postCopy` is a hook that gives you an opportunity to copy instance variables by overriding `postCopy`. For more information, see Chapter 22, Common Errors and Chapter 25, Hooks into the System.
## Dependents access

The messages `addDependent:` and `removeDependent:` provide the basic mechanism for setting up and closing down a dependency relationship on another object. The messages `expressInterestIn:` for `sendBack:` and `retractInterestIn:` for `sendBack:` provide a more sophisticated mechanism. There is more information on these messages in Chapter 19, The Dependency Mechanism.

## Error handling

The message `subclassResponsibility` is sent in methods that should be overridden by subclasses. The typical use is for the superclass method to do `self subclassResponsibility`. If a subclass fails to override the method, an exception is raised. The opposite message, `shouldNotImplement` is sent in a subclass method to show that although the subclass has inherited the method, it is not appropriate behavior for this subclass. The messages `halt`, `halt:`, `error:`, and `notify:` are all used to generate exceptions and raise a Notifier/Debugger window (for example, `self halt`). The messages `errorSignal` and `messageNotUnderstoodSignal` return signals that can be used in signal handlers to trap exceptions. The message `doesNotUnderstand:` is sent when a message is not understood by the receiver, and its default behavior is to raise a Notifier/Debugger window. Override this method if you want to trap messages that were not understood so you can pass them to another object. We use this mechanism in Chapter 21, Debugging.

## File In/Out

The messages `binaryRepresentationVersion` and `representBinaryOn:` provide specialized behavior for use with the BOSS facility when storing and retrieving binary objects. In particular, by overriding `representBinaryOn:`, you can specify how you want an object to be stored. Returning `nil`, which is the default implementation, says to store the default representation of the receiver. Returning 0 says to not store the object at all. The other common return is a `MessageSend`, which provides a way to store the object in one form and reconstitute it in a different form when it is read back.

## Initialize-release

The `release` message breaks any dependencies that may have been established on this object. It is sent when the object is no longer needed and allows the object to be garbage-collected.

## Message handling

The `perform:` family of messages allow you to create a method name at runtime then invoke the method. It is widely used when you don't know the name of the method at compile time and have to wait until runtime. For example, the user interface uses it heavily since the names of the accessor methods for variables and menus are specified by the user when building the user interface, but the underlying user interface code is part of the system classes. We'll talk more about the `perform:` messages in Chapter 28, Eliminating Procedural Code and we'll use it in Chapter 30, Testing.
## Printing

The most commonly used methods in the printing protocol are `printString`, `printOn:`, and `displayString`. You send `printString` to an object to get a printable representation, one that can be shown on the Transcript. The `printString` message invokes `printOn:`, so to override what `printString` returns, you override `printOn:`. The `displayString` message returns a more suitable representation of the receiver for use in labels and list boxes (SequenceViews). It defaults to `printString`, but is overridden by classes such as `String`.

## System primitives

The messages `allOwners` and `allOwnersWeakly`: return collections of objects that reference the receiver. The messages `firstOwner` and `ownerAfter`: return individual objects from those collections. The `become`: message swaps the references of two objects. One use of `become`: is when collections grow in size. A new collection is created, the elements are copied across, and the new collection becomes the old collection. The messages `instVarAt:` and `instVarAt:put`: allow you direct access to instance variables without having to name them. However, since use of these two methods violates encapsulation, they should be used sparingly, if at all.

## Testing

This protocol contains methods that return `true` or `false`. Most of the methods return `false`, allowing them to be overridden when appropriate. For example, `isInteger` returns `false`, but is overridden in `Integer` to return `true`. The `isBehavior` message tells if the receiver can be the class of another object. The `isImmediate` message tells if the receiver is an immediate object such as a `SmallInteger` or a `Character` that can be represented in thirty-two bits, or whether the receiver is being represented by an object pointer. The messages `isNil` and `notNil` tell whether the object is `nil` and are overridden by `UndefinedObject`. The message `isSequenceable` tells if the object is a sequenceable collection — ie, a subclass of `SequenceableCollection`. The message `isString` tells if the object is a `String`, and `isSymbol` tells if it is a `Symbol`. The `respondsToArithmetic` message tells if the object belongs to a subclass of `ArithmeticValue`.

Use of testing messages allows you to avoid messages such as `isKindOf:` and `isMemberOf:`. In your own classes, use `isXXX` types of messages if you need to determine if an object is of a particular type. For example, suppose you have a `Response` class with subclasses of `SuccessResponse` and `FailureResponse`. In `Response`, implement the methods `isResponse`, `isSuccessResponse` and `isFailureResponse`, with the first returning `true` and the next two returning `false`. `SuccessResponse` should override `isSuccessResponse` to return `true`, and `FailureResponse` should override `isFailureResponse` to return `true`. If you have many different types of domain objects for which you want to implement `isXXX` type messages, consider creating an `ApplicationObject` that is subclassed off `Object`, where you write a series of `isXXX` methods, each returning `false`. Then in each domain class you override the corresponding testing method, returning `true`.
## Updating

The methods in this protocol that you are most likely to be interested in are the `update:` family — `update:`, `update:with:`, and `update:with:from:`. These are all used in the dependency mechanism to inform dependents about changes. An object that changes sends itself a message from the `changed:` family, and eventually these messages send a message from the `update:` family to each dependent. Dependents therefore need to override one of the `update:` messages if they want to take action based on the notification. We talk more about the dependency mechanism in Chapter 19, The Dependency Mechanism.

## User interface

The `browse` message opens a class Browser on the class of the receiver. The `inspect` message opens an Inspector on the receiver. This message is overridden by some classes to provide an Inspector more suitable for the class. For example OrderedCollection overrides `inspect` to hide the internal implementation details of the collection. To see the internal details you can send the message `basicInspect`, which shows all the instance variables of an object. Figure 10-1 shows an instance of OrderedCollection inspected by sending first `inspect` and then `basicInspect`.

<figure><img src="image_12.png" /><figcaption>Figure 10-1. Inspecting using `inspect` and `basicInspect`.</figcaption></figure>
11

Collections

Collections are objects that contain a group of other objects. Collections are among the most useful classes in Smalltalk and you'll find yourself using them constantly — even a string is nothing more than a collection of characters. The top level collection class is *Collection*, which is an abstract superclass that provides the generic behavior common to all collections. For example, *Collection* implements the methods *size* and *capacity*, the testing methods *empty?*, *contains*:, and *includes*:, the converting methods such as `asArray`, `asOrderedCollection`, the powerful enumeration methods such as `do:` and `collect:`, and the basic adding and removing methods `add:`, `remove:`, and `remove:ifAbsent:`. (Many of these methods are inherited by subclasses of *Collection*, but some act as placeholders to tell subclasses they should implement the method appropriately.)

The main subclasses of *Collection* that you will use are *Bag*, *Set*, and *SequenceableCollection*. *SequenceableCollection* is an abstract superclass for all the collections that understand sequencing, such as *Array*, *OrderedCollection*, and *String*. Because it expects all its subclasses to understand the concept of sequencing, *SequenceableCollection* adds behavior such as *first* and *last*, which is not generic enough to be placed in *Collection*. As we go further down the hierarchy, each subclass provides increasingly specific functionality, sometimes by adding new methods and sometimes by overriding methods defined in one of its superclasses. The hierarchy of basic collection classes that you will use is shown in Figure 11-1.
<figure><img src="image_13.png" /><figcaption>**Figure 11-1.** The basic collection hierarchy.</figcaption></figure>

Not described here, but worth looking at so you know of their existence are: *IdentitySet*, *WeakDictionary*, *Symbol*, *IntegerArray*, *ByteArray*, *WordArray*, *RunArray*, *WeakArray*, and *KeyedCollection*.

Unfortunately, the hierarchy doesn't tell us as much as we'd like about the operations that can be performed. For example, if we look at removing items from a collection, Bags and Sets allow removal. In the SequenceableCollection hierarchy, Intervals don't allow removal, but LinkedLists and OrderedCollections do. Most ArrayedCollections don't allow removal, but Lists do allow it. So we'll try to generalize where possible, but will largely have to consider each class on its own.

Because there is so much specific functionality associated with collections, we will look at mainly the basic functionality. We'll start by looking at the main types of collection, with a brief explanation of how to use them and when you might use them. Then we'll take a look at the general mechanism for creating a collection, at the general aspects of adding objects and removing objects, at the powerful enumeration methods that are used to loop through collections, and at the general messages that collections understand. However, there is a vast amount of behavior that I've left out so it's well worth spending some time looking through the Collection hierarchy. If you use a Full Browser (from the VisualWorks Advanced Tools) and switch on supers, you will get a better feel for what behavior is inherited and what is implemented by each collection you look at.

## Collection types

In what follows, note that collection indexing schemes are 1-based, rather 0-based as in C or C++. If the collection allows indexing, such as an Array or an OrderedCollection, the first element has index 1.

### OrderedCollection

OrderedCollection is the workhorse of collection; I use OrderedCollections and Dictionaries more than any other types of collection. OrderedCollection stores objects in the order they were added, and will grow and shrink as you add and remove objects. Because the size is dynamic, OrderedCollections are generally more useful than Arrays, which are not dynamic. Because OrderedCollections are sequenced, you can use them as queues (FIFO) or stacks (LIFO). Here's an example that shows the chronological sequencing of OrderedCollection. You will see the string 'xyz' if you do the following.

orderedCollection := OrderedCollection new.
orderedCollection add: 'xyz'; add: 'abc'.
orderedCollection first inspect

The basic operations to add and remove items in an OrderedCollection are `add:`, `remove:` and `remove:ifAbsent:`. This last message is useful because `remove:` raises an exception if the object is not present. For example,

orderedCollection := OrderedCollection new.
orderedCollection add: #here.
orderedCollection remove: #here.
orderedCollection remove: #there ifAbsent: [nil].

OrderedCollections also understand a lot of messages related to order of objects in the collection, such as `first`, `last`, `after:` and `before:`.

## SortedCollection

If you want the objects sorted according to some collating sequence, use a SortedCollection. SortedCollection is subclassed off OrderedCollection and inherits most of its behavior. The main difference between a SortedCollection and an OrderedCollection is the order in which it keeps its elements. SortedCollection keeps its elements in sorted order by comparing pairs of elements. It's default mechanism is to send the `<=` message to one element, passing the second element as a parameter. The alternative way is for the programmer to specify a block of code that will compare two objects, in which case the SortedCollection executes the block for pairs of elements.

If you let the SortedCollection send the `<=` message, the only requirement is that each object you add to the collection responds to the `<=` message and returns `true` if it is less than or equal to the parameter object, and `false` otherwise. This generally means that SortedCollections will contain homogeneous objects, objects of the same type. Numbers and strings both know how to respond to `<=` but if you are storing your own objects, you will need to implement `<=`. Your implementation may compare the values of instance variables, or may do something as simple as

MyClass>> <= anObject
^self printString <= anObject printString

If you choose to specify the sort algorithm, you can create an instance of SortedCollection by sending the `sortBlock:` message to the SortedCollection class. The parameter is the block of code that does the comparison. For example,

sortedCollection := SortedCollection sortBlock: [ :x :y | x name < y name]

Alternatively, you can specify a new sort algorithm by sending the `sortBlock:` `aSortBlock` message to the instance of SortedCollection. This causes the collection to be resorted, and any additions to be put in the correct place. You can create a new instance of SortedCollection, with a different sort sequence, by sending a collection the message `asSortedCollection:` `aSortBlock`.

Keeping elements in sorted order makes it expensive to add objects. If you spend a lot more time adding elements than reporting on elements, there are three options that are more efficient. The first is to use a List,
which is described below. The second is to use an OrderedCollection, then to ask a
`SequenceableCollectionSorter` to sort it in place when required. The easiest way to do this is to send the
messages `sort:` or `sort:using:` to the `SequenceableCollectionSorter` class. For example, the following
code sorts the array in place, giving `(1 2 3 4 5)`.

```
array := # (5 4 3 2 1).
SequenceableCollectionSorter sort: array.
array inspect.
```

The third option is to send the collection `asSortedCollection` or `asSortedCollection:` if you
don't mind getting back a new collection.

List

List is a collection that provides the chronological ordering (and indexing) of OrderedCollection, the sorting of SortedCollection, and the dependency notification of Model. Because of their dependency notification, Lists are used by both SelectionInList and MultiSelectionInList in user interface applications. Because of the versatility of Lists, there is a school of thought that says Lists should be used instead of OrderedCollections and SortedCollections. (For a time I did just this, but have now gone back to using the OrderedCollection as my workhorse. I liked having to type in only four characters for the class name, but disliked the seeming lack of elegance of a List. In particular, I like my classes to do one thing well, but a List tries to be all things to all people. Also, I never really liked inspecting a List.)

To sort a List in place, simply send it the `sort` message, or the `sortWith:` message to specify a sort
algorithm. Internally, Lists use a `SequenceableCollectionSorter` to sort themselves.

Array

Arrays are fixed size collections where objects are stored in fixed locations, referenced by integer indexes.
Since Arrays are fixed size, you can't add to the end of an array or delete elements from an array. However,
Arrays provide faster accessing than other collections and are most useful when there will be lots of accessing.
Unlike C and C++, where all elements of an array must be of the same type, in Smalltalk, array elements can be
of arbitrary type. The disadvantage of Arrays are that you need to know the size of the array when you create it
and they are of fixed size <fnref n="1" />.

If you send the `new` message to Array, you get an instance of Array with a size of 0, so the usual way to
create an instance of Array is to send the `new:` message and specify the size. For example,

```
array := Array new: 10.
```

The usual way to access an array is to send `at:put:` to put an object in the array and `at:` to retrieve the
object at an index. The parameter to `at:` must be an integer. For example,

```
array at: 3 put: anObject.
anObject := array at: 3.
```

<footnote n="1">¹ Actually, you can grow an array in one of two ways: by sending `changeSizeTo:` or `grow` to it, or by
creating a Stream on the Array, the latter being the preferred technique. We'll talk more about Streams in
Chapter 13, Streams.</footnote>
## Dictionary

Dictionary is one of my favorite classes. A Dictionary is a collection where you look up values based on a key, and the key can be any object (except `nil`). A Dictionary is like an Array in that you access it using `at:` and `at:put:`. However, whereas Arrays are fixed size and you need an integer index to access elements, a Dictionary can automatically grow, and you can access elements using any object as a key. For example,

```
dictionary := Dictionary new.
dictionary at: 'abc' put: 'def'.
```

Dictionaries store Associations, so besides `at:put:`, you can add Associations directly to a Dictionary. The example above could also be written as one of:

```
dictionary := Dictionary new.
dictionary add: 'abc' -> 'def'.

dictionary := Dictionary new.
dictionary add: (Association key: 'abc' value: 'def').
```

To remove an object from a Dictionary, send either the `removeKey:` or `removeKey:ifAbsent:` message.

In the section on centralized error messages in Chapter 20, Error Handling, we'll see the use of Dictionaries with symbols as their keys. If you choose to use objects of your own creation as keys, you will need to implement `=` and `hash` for your object (whenever you implement `=`, you need to implement `hash` because two objects that are equal should also generate the same hash value).

IdentityDictionary uses `==` rather than `=` to compare keys, so it is a little faster than Dictionary if you have symbols for keys. Since many Dictionaries use symbols for their keys, you'll often find IdentityDictionaries used in preference to Dictionary. However, where Dictionaries keep a collection of Associations, IdentityDictionaries keep two parallel collections for keys and values. Because of the way PoolDictionaries are implemented, you can't use an IdentityDictionary as a PoolDictionary.

## Set

A Set is an unordered collection of unique objects, so if you want a collection that guarantees no duplicates, use a Set. There is no structured accessing of a Set because there is no order to the elements. Instead, the way to access the elements of a Set is through the enumeration messages described below. If you try to add an object that already exists, the Set silently ignores it. If you try the following, you'll see a size of 2 since nothing was added when we tried to add the duplicate 7.

```
set := Set new add: 7; add: 8; add: 7; yourself.
set size inspect
```

When adding an object, a Set uses both the `hash` and `=` messages to determine if it is a duplicate of any other object in the collection. Sets are fairly expensive if you are doing a lot of adding, so use them only when you specifically want the property of uniqueness. One use of Set is to test for duplicates in a collection; for example, the following gives a Boolean that says whether the collection includes duplicate items.

```
includesDuplicates := collection size ~~ collection asSet size.
```
## Bag

A Bag is another unordered collection that contains objects of arbitrary type. It is very similar to a Set except that a Bag keeps track of the number of occurrences of each object. Like a Set, it sends both `hash` and `==` to determine if an object already exists in the collection. One use of a Bag would be to collect duplicate items from another type of collection by doing something like the following. However, I've never seen a Bag used in an application.

```
duplicateList := List new.
collection asBag valuesAndCountsDo:
    [:each :count | count > 1 ifTrue: [duplicateList add: each]].
```

## LinkedList

A LinkedList is a collection where each element points to the next element. OrderedCollections can do everything LinkedLists can do, the only difference being that LinkedLists are more efficient at doing large numbers of inserts and deletes. Elements of a LinkedList must be instances of *Link* or one of its subclasses (or at least be polymorphic with *Link* — respond to the same messages), which means that you will usually create a new subclass of *Link* in order to use a LinkedList. VisualWorks uses LinkedLists to manage processes, so *Process* is defined as a subclass of *Link*. This is the only example of LinkedList I've seen used.

## Creating new collections

There are three usual ways to create a collection. One is to send the *new* message to the collection class. The second is to send *new: aCapacity*. The third is to use a message from the *with*: family and pass in the initial elements of the collection.

### new:

The underlying instance creation mechanism is to use `new:`, which is implemented as a primitive by the class *Behavior*. Some of the collection classes override `new:`, usually invoking `super new:` then adding class specific code. `new:` creates an instance of a collection with indexed variables, where the parameter to `new:` specifies the number of indexed variables. (You can tell if a class is indexed because the top line of the class definition will say `variableSubclass:` rather than `subclass:`. The other type of variable is the named variable, which is an instance variable with a name.) For fixed size collections such as Array, the parameter to `new:` is both the capacity and the size of the collection. For collections that can grow, such as OrderedCollection, the collection has an initial size of 0, and the parameter specifies the capacity — the number of elements the collection can hold before it has to grow.

Because `new:` is used to specify a capacity, it's poor style to use `new:` to pass in parameters other than the capacity. When writing your own classes, it's better style to use `with:`, or to specify the parameter type in the instance creation message, such as `newLabel:`.
## new

The new message is also implemented by Behavior but is overridden by the collection classes, and is usually implemented by sending `new: someInitialSize`. For example,

```
OrderedCollection class>>new
^self new: 5
```

Many collections will grow automatically as you add to them, so you don't need to specify an initial size and can simply send new. However, growing a collection is expensive, so if you know how large the collection will be, it's more efficient to send the new: message, specifying the size. In a timing test, it took over three times as long to add a hundred items to an OrderedCollection when the OrderedCollection was created using new as when it was created using new:. The first example took 1253 microseconds while the second example took 372 microseconds.

```
orderedCollection := OrderedCollection new.
1 to: 100 do: [:index | orderedCollection add: index]

orderedCollection:= OrderedCollection new: 100.
1 to: 100 do: [:index | orderedCollection add: index]
```

## The with: family

You can create a collection and populate it with some initial elements by sending the class a message from the with: family of messages. There are five messages, each specifying a different number of objects to add. If you want to add more than four objects, they must already be in a collection of some type (in which case you could have sent the original collection the asSomeTypeOfCollection message; for example, asOrderedCollection).

```
with: objectOne
with: objectOne with: objectTwo
with: objectOne with: objectTwo with: objectThree
with: objectOne with: objectTwo with: objectThree with: objectFour
withAll: aCollectionOfObjects
```

For example,

```
collection := OrderedCollection with: 'how' with: 'are' with: 'you'.
collection := List withAll: #('how' 'are' 'you' 'today' 'Alec?').
```

## Adding to and removing from Collections

The standard messages to add elements to a collection are at:put: for keyed collections such as Array and Dictionary, and add: for collections such as Bag, Set, and OrderedCollection. The general behavior when adding to or removing from a collection is to return the object being added or removed. Thus, both add: and at:put: return the object being stored. When you add to a collection, the collection may have to grow to fit in the new object. OrderedCollections will grow in size automatically when necessary. For more information, see the section on Growing Collections below. An alternative, and efficient approach to adding objects to collections is to create a Stream on the collection. We'll talk more about Streams in Chapter 13, Streams.
A common bug when using `add:` is forgetting that `add:` returns the object added rather than `self`. So, if you are creating a collection and adding to it, the following will *not* give you what you expect.

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

Instead, use one of the following techniques.

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

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

The standard messages to remove elements from a collection are `remove:` and `remove:ifAbsent:`. For keyed collections such as `Dictionary`, use `removeKey:` and `removeKey:ifAbsent:`. Note that you can't remove elements from an Array. When you send `remove:`, the object that was removed will be returned. If the object can't be found in the collection, an exception is raised. The alternative message `remove:ifAbsent:` will return the object if it is successfully removed. If the object can't be found, it will execute the block of code passed as the parameter to `ifAbsent:`, returning the value of the block.

A subtle `remove:` bug is to iterate over a collection and remove from the same collection. This will cause problems as the collection may be reorganized underneath you when you remove elements. Instead, you should iterate over a copy of the collection and remove from the original collection. For example,

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

Sometimes you don't even need to remove objects explicitly. Instead, you can use `select:` or `reject:` to create a new collection. We'll talk more about these messages below, in the section on Enumerating, but here are examples of doing the above operation using these two messages.

```python
collection:= OrderedCollection withAll: #(1 2 3 4 5 6).
collection select: [:each | each odd].

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

## Enumerating

One reason it is difficult to have off-by-one errors or array size errors in Smalltalk is that collections provide some very powerful ways of iterating through their elements without having to specify sizes or bounds.
Collections *know* how big they are. Methods that do things over all the elements of a collection live in the *enumerating* protocol.

The enumeration messages go through each element in the collection, executing a block of code for each element. The block of code always takes the element as a parameter. In the examples below, you'll see that instead of getting fancy with the parameter name, I use *each* (I also use *index* for objects that are guaranteed to be index numbers). This has the benefit that if you see *each* or *index* you know it refers to the collection element being processed. You can usually tell what the item is from the collection name or from where it was built.

**do:**

The `do:` message is the basic enumeration message. It goes through all the items in the collection (in order, if the collection is sequenceable) and performs a programmer-specified block of code for each item in the collection. For example,

```ruby
#(1 2 3 4 5) do: [ :each | Transcript cr; show: each printString].
```

The block is executed for each item in the collection and is passed that item as a parameter. Use `do:` when you want to perform some action for all or some of the elements in the collection. If you just want to create a new collection, use one of the messages below. The method `reverseDo:` iterates over the collection in reverse.

If you send `do:` to a Dictionary, it iterates through the values in the Dictionary. Three other methods, `keysDo:`, `associationsDo:`, and `keysAndValuesDo:` iterate over the keys, the associations, and the key and value pairs.

Another message, `with:do:`, allows you to iterate over two parallel collections, passing corresponding elements from the two collections to the `do:` block.

**collect:**

The `collect:` message allows you to do something for each item in the collection and puts the result of your action in a new collection. For example, if you wanted to create a new collection of the squares of a collection of numbers you could do either of the following. However, `collect:` is both better style and is more efficient because it doesn't use any variables declared outside the block. A timing test showed the first technique taking 103 microseconds while the second technique took 31 microseconds.

```ruby
squareCollection := List new.
#(1 2 3 4 5) do: [ :each | squareCollection add: each * each].
squareCollection := #(1 2 3 4 5) collect: [ :each | each * each].
```

It's useful to remember `collect:` because it's easy to find yourself writing code similar to the first example when you should be using `collect:`. Any time you iterate over a collection and add objects to another collection, consider using `collect:` or `select:`.
**select:**

The `select:` message allows you to create a subcollection where items from the original collection are selected based on some condition being true for them. For example, we get the result `(1 3 5)` from the following example.

```
#(1 2 3 4 5) select: [ :each | each odd].
```

**reject:**

The `reject:` message is similar to `select:` but works the opposite way — items are rejected from the new subcollection if the condition is true. Using the same example as for `select:` we get the array `(2 4)`.

```
#(1 2 3 4 5) reject: [ :each | each odd].
```

**detect:**

The `detect:` message returns the first item in a collection that satisfies a condition. For example, we get the value `4` from the following example.

```
(1 to: 5) detect: [ :each | each > 3].
```

If no item satisfies the condition, an exception is raised. You can avoid this by using `detect:ifNone:` and providing another block which is executed if no item satisfies the condition. For example, we get the value `99` from this example.

```
(1 to: 5) detect: [ :each | each > 30] ifNone: [99].
```

**inject:into:**

The `inject:into:` message is a strange message. Some people never use it, while others love it and use it whenever possible. The classic example is subtotaling.

```
(1 to: 5) inject: 0 into: [ :subtotal :each | subtotal + each].
```

When the block is executed for the first item in the collection, the parameter to the `inject:` keyword is passed in as the first parameter. The block returns `subtotal + each`, which for the first item is `0 + 1`. This returned value is then used as the first parameter for the next invocation of the block. Each invocation, the block returns a value which is passed in as the first parameter for the next invocation. In fact, it might be easier to understand if we wrote the above example as:

```
(1 to: 5) inject: 0 into: [ :injectedValue :each | injectedValue + each].
```

It takes a while to get used to `inject:into:` and to figure out situations where it is useful. To make this process a little shorter, here are some examples of its use. Inspect the results and understand what each example is doing.

```
(1 to: 5) inject: 0 into: [ :max :each | max max: each].
```
(1 to: 5) inject: 1 into: [ :factorial :each | factorial * each ].

#('Now' 'is' 'the' 'time' 'for' 'all' 'good' 'men')
inject: String new
into: [ :string :each | string, each, ' '].

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

Note that in this last example, we send `yourself` as the last message to make sure that the stream is returned from the block. A common error is to not return the object that will be injected in the next iteration. In this case we didn't actually need `yourself`, but it's good practice to send it just to make sure the correct object is returned.

## Enumeration wrap-up

<figure><img src="image_14.png" /><figcaption>**Figure 11-2.** Implementing behavior in terms of subclass responsibilities.</figcaption></figure>

The abstract superclass *Collection* implements all the enumeration methods in terms of `do:`. By requiring the subclasses of Collection to implement `do:` in a way that is appropriate for the subclass, the other enumeration methods can then be defined by Collection and inherited by all its subclasses. This is shown in Figure 11-2. It illustrates the useful object-oriented technique of having an abstract superclass implement behavior in terms of a few undefined methods that are implemented by its subclasses.

## General messages for collections

Below are some of the messages that collections respond to. I've listed them here to give you a feel for the types of things you can do. However, not all collections respond to all the messages. For example, some of them only make sense with collections that have a concept of sequence, while others only make sense in collections where you can remove items.