<figure><img src="image_132.png" /><figcaption>**Figure 13.7:** A CrossMorph with its halo; you can resize it as you wish.</figcaption></figure>

## 13.4 Creating and drawing your own morps

While it is possible to make many interesting and useful graphical representations by composing morps, sometimes you will need to create something completely different.

To do this you define a subclass of Morph and override the drawOn: method to change its appearance.

The morphic framework sends the message drawOn: to a morph when it needs to redisplay the morph on the screen. The parameter to drawOn: is a kind of Canvas; the expected behaviour is that the morph will draw itself on that canvas, inside its bounds. Let's use this knowledge to create a cross-shaped morph.

Using the browser, define a new class CrossMorph inheriting from Morph:

```FLASH
Morph subclass: #CrossMorph
instanceVariableNames: ''
classVariableNames: ''
package: 'PBE-Morphic'
```

We can define the drawOn: method like this:

```FLASH
CrossMorph >> drawOn: aCanvas
    | crossHeight crossWidth horizontalBar verticalBar |
    crossHeight := self height / 3.0.
    crossWidth := self width / 3.0.
    horizontalBar := self bounds insetBy: 0 @ crossHeight.
    verticalBar := self bounds insetBy: crossWidth @ 0.
    aCanvas fillRectangle: horizontalBar color: self color.
    aCanvas fillRectangle: verticalBar color: self color
```

Sending the bounds message to a morph answers its bounding box, which is an instance of Rectangle. Rectangles understand many messages that create other rectangles of related geometry. Here, we use the insetBy: message with a point as its argument to create first a rectangle with reduced height, and then another rectangle with reduced width.

To test your new morph, execute CrossMorph new openInWorld.
The result should look something like Figure 13.7. However, you will notice that the sensitive zone — where you can click to grab the morph — is still the whole bounding box. Let's fix this.

When the Morphic framework needs to find out which Morphs lie under the cursor, it sends the message `containsPoint`: to all the morphs whose bounding boxes lie under the mouse pointer. So, to limit the sensitive zone of the morph to the cross shape, we need to override the `containsPoint:` method.

Define the following method in class `CrossMorph`:

```ruby
CrossMorph >> containsPoint: aPoint
  | crossHeight crossWidth horizontalBar verticalBar |
  crossHeight := self height / 3.0.
  crossWidth := self width / 3.0.
  horizontalBar := self bounds insetBy: 0 @ crossHeight.
  verticalBar := self bounds insetBy: crossWidth @ 0.
  ^ (horizontalBar containsPoint: aPoint) or: [ verticalBar
                                           containsPoint: aPoint ]
```

This method uses the same logic as `drawOn:`, so we can be confident that the points for which `containsPoint:` answers true are the same ones that will be colored in by `drawOn`. Notice how we leverage the `containsPoint:` method in class `Rectangle` to do the hard work.

There are two problems with the code in the two methods above.

The most obvious is that we have duplicated code. This is a cardinal error: if we find that we need to change the way that `horizontalBar` or `verticalBar` are calculated, we are quite likely to forget to change one of the two occurrences. The solution is to factor out these calculations into two new methods, which we put in the private protocol:

```ruby
CrossMorph >> horizontalBar
  | crossHeight |
  crossHeight := self height / 3.0.
  ^ self bounds insetBy: 0 @ crossHeight

CrossMorph >> verticalBar
  | crossWidth |
  crossWidth := self width / 3.0.
  ^ self bounds insetBy: crossWidth @ 0
```

We can then define both `drawOn:` and `containsPoint:` using these methods:

```ruby
CrossMorph >> drawOn: aCanvas
  aCanvas fillRectangle: self horizontalBar color: self color.
  aCanvas fillRectangle: self verticalBar color: self color
```

```ruby
CrossMorph >> containsPoint: aPoint
  ^ (self horizontalBar containsPoint: aPoint) or: [ self verticalBar
                                                   containsPoint: aPoint ]
```
<figure><img src="image_133.png" /><figcaption>**Figure 13.8:** The center of the cross is filled twice with the color.</figcaption></figure>

<figure><img src="image_134.png" /><figcaption>**Figure 13.9:** The cross-shaped morph, showing a row of unfilled pixels.</figcaption></figure>

This code is much simpler to understand, largely because we have given meaningful names to the private methods. In fact, it is so simple that you may have noticed the second problem: the area in the center of the cross, which is under both the horizontal and the vertical bars, is drawn twice. This doesn't matter when we fill the cross with an opaque colour, but the bug becomes apparent immediately if we draw a semi-transparent cross, as shown in Figure 13.8.

Execute the following code in a playground, line by line:

```Flash
CrossMorph new openInWorld;
    bounds: (0@0 corner: 200@200);
    color: (Color blue alpha: 0.4)
```

The fix is to divide the vertical bar into three pieces, and to fill only the top
and bottom. Once again we find a method in class `Rectangle` that does the hard work for us: `r1 areasOutside: r2` answers an array of rectangles comprising the parts of `r1` outside `r2`. Here is the revised code:

```FLASH
CrossMorph >> drawOn: aCanvas
    | topAndBottom |
    aCanvas fillRectangle: self horizontalBar color: self color.
    topAndBottom := self verticalBar areasOutside: self horizontalBar.
    topAndBottom do: [ :each | aCanvas fillRectangle: each color: self
                      color ]
```

This code seems to work, but if you try it on some crosses and resize them, you may notice that at some sizes, a one-pixel wide line separates the bottom of the cross from the remainder, as shown in Figure 13.9. This is due to rounding: when the size of the rectangle to be filled is not an integer, `fillRectangle:` `color:` seems to round inconsistently, leaving one row of pixels unfilled. We can work around this by rounding explicitly when we calculate the sizes of the bars.

```FLASH
CrossMorph >> horizontalBar
    | crossHeight |
    crossHeight := (self height / 3.0) rounded.
    ^ self bounds insetBy: 0 @ crossHeight
```

```FLASH
CrossMorph >> verticalBar
    | crossWidth |
    crossWidth := (self width / 3.0) rounded.
    ^ self bounds insetBy: crossWidth @ 0
```

## 13.5 Interaction and animation

To build live user interfaces using morphs, we need to be able to interact with them using the mouse and keyboard. Moreover, the morphs need to be able respond to user input by changing their appearance and position — that is, by animating themselves.

### Mouse events

When a mouse button is pressed, Morphic sends each morph under the mouse pointer the message `handlesMouseDown:`. If a morph answers true, then Morphic immediately sends it the `mouseDown:` message; it also sends the `mouseUp:` message when the user releases the mouse button. If all morphs answer false, then Morphic initiates a drag-and-drop operation. As we will discuss below, the `mouseDown:` and `mouseUp:` messages are sent with an argument — a `MouseEvent` object — that encodes the details of the mouse action.

Let's extend `CrossMorph` to handle mouse events. We start by ensuring that all `crossMorphs` answer true to the `handlesMouseDown:` message.
<figure><img src="image_135.png" /><figcaption>**Figure 13.10:** Move Handle button.</figcaption></figure>

<figure><img src="image_136.png" /><figcaption>**Figure 13.11:** Grab Handle button.</figcaption></figure>

Add this method to `CrossMorph`:

```Flash
CrossMorph >> handlesMouseDown: anEvent
    ^ true
```

Suppose that when we click on the cross, we want to change the color of the cross to red, and when we action-click on it, we want to change the color to yellow. This can be accomplished by the `mouseDown:` method as follows:

```Flash
CrossMorph >> mouseDown: anEvent
    anEvent redButtonPressed
        ifTrue: [ self color: Color red ]. "click"
    anEvent yellowButtonPressed
        ifTrue: [ self color: Color yellow ]. "action-click"
    self changed
```

Notice that in addition to changing the color of the morph, this method also sends `self changed`. This makes sure that morphic sends `drawOn:` in a timely fashion.

Note also that once the morph handles mouse events, you can no longer grab it with the mouse and move it. Instead you have to use the `halo:` meta-click on the morph to make the halo appear and grab either the brown move handle (see Figure 13.10) or the black pickup handle (see Figure 13.11) at the top of the morph.

The `anEvent` argument of `mouseDown:` is an instance of `MouseEvent`, which is a subclass of `MorphicEvent`. `MouseEvent` defines the `redButtonPressed` and `yellowButtonPressed` methods. Browse this class to see what other methods it provides to interrogate the mouse event.

## Keyboard events

To catch keyboard events, we need to take three steps.

1. Give the keyboard focus to a specific morph. For instance, we can give focus to our morph when the mouse is over it.

2. Handle the keyboard event itself with the `handleKeystroke:` method. This message is sent to the morph that has keyboard focus when the user presses a key.
3. Release the keyboard focus when the mouse is no longer over our morph.

Let's extend `CrossMorph` so that it reacts to keystrokes. First, we need to arrange to be notified when the mouse is over the morph. This will happen if our morph answers `true` to the `handlesMouseOver:` message

Declare that `CrossMorph` will react when it is under the mouse pointer.

```Groovy
CrossMorph >> handlesMouseOver: anEvent
    ^true
```

This message is the equivalent of `handlesMouseDown:` for the mouse position. When the mouse pointer enters or leaves the morph, the `mouseEnter:` and `mouseLeave:` messages are sent to it.

Define two methods so that `CrossMorph` catches and releases the keyboard focus, and a third method to actually handle the keystrokes.

```Groovy
CrossMorph >> mouseEnter: anEvent
    anEvent hand newKeyboardFocus: self
```

```Groovy
CrossMorph >> mouseLeave: anEvent
    anEvent hand newKeyboardFocus: nil
```

```Groovy
CrossMorph >> handleKeystroke: anEvent
    | keyValue |
    |         |
    | keyValue := anEvent keyValue. |
    |         |
    | keyValue = 30 "up arrow" |
    |         | ifTrue: [self position: self position - (0 @ 1)]. |
    |         |
    | keyValue = 31 "down arrow" |
    |         | ifTrue: [self position: self position + (0 @ 1)]. |
    |         |
    | keyValue = 29 "right arrow" |
    |         | ifTrue: [self position: self position + (1 @ 0)]. |
    |         |
    | keyValue = 28 "left arrow" |
    |         | ifTrue: [self position: self position - (1 @ 0)]. |
    |         |
```

We have written this method so that you can move the morph using the arrow keys. Note that when the mouse is no longer over the morph, the `handleKeystroke:` message is not sent, so the morph stops responding to keyboard commands. To discover the key values, you can open a Transcript window and add `Transcript show: anEvent keyValue` to the `handleKeystroke:` method.

The `anEvent` argument of `handleKeystroke:` is an instance of `KeyboardEvent`, another subclass of `MorphicEvent`. Browse this class to learn more about keyboard events.

## Morphic animations

`Morphic` provides a simple animation system with two main methods: `step` is sent to a morph at regular intervals of time, while `stepTime` specifies the time
<figure><img src="image_137.png" /><figcaption>**Figure 13.12:** The debug handle button.</figcaption></figure>

in milliseconds between steps. stepTime is actually the *minimum* time between steps. If you ask for a stepTime of 1 ms, don't be surprised if Pharo is too busy to step your morph that often. In addition, startStepping turns on the stepping mechanism, while stopStepping turns it off again. isStepping can be used to find out whether a morph is currently being stepped.

Make `CrossMorph` blink by defining these methods as follows:

```ruby
CrossMorph >> stepTime
^ 100

CrossMorph >> step
(self color diff: Color black) < 0.1
    ifTrue: [ self color: Color red ]
    ifFalse: [ self color: self color darker ]
```

To start things off, you can open an inspector on a `CrossMorph` using the debug handle (see Figure 13.12) in the morphic halo, type `self startStepping` in the small playground pane at the bottom, and Do it.

Alternatively, you can modify the `handleKeystroke:` method so that you can use the + and - keys to start and stop stepping. Add the following code to the `handleKeystroke:` method:

```ruby
keyValue = $+ asciiValue
    ifTrue: [ self startStepping ].
keyValue = $- asciiValue
    ifTrue: [ self stopStepping ].
```

## 13.6 Interactors

To prompt the user for input, the `UIManager` class provides a large number of ready to use dialog boxes. For instance, the `request:initialAnswer:` method returns the string entered by the user (Figure 13.13).

```ruby
UIManager default request: 'What''s your name?' initialAnswer: 'no name'
```

To display a popup menu, use one of the various `chooseFrom:` methods (Figure 13.14):

```ruby
UIManager default
    chooseFrom: #('circle' 'oval' 'square' 'rectangle' 'triangle')
    lines: # (2 4) message: 'Choose a shape'
```

Browse the `UIManager` class and try out some of the interaction methods offered.
<figure><img src="image_138.png" /><figcaption>**Figure 13.13:** An input dialog.</figcaption></figure>

<figure><img src="image_139.png" /><figcaption>**Figure 13.14:** Pop-up menu.</figcaption></figure>

## 13.7 Drag-and-drop

Morphic also supports drag-and-drop. Let's examine a simple example with two morphs, a receiver morph and a dropped morph. The receiver will accept a morph only if the dropped morph matches a given condition: in our example, the morph should be blue. If it is rejected, the dropped morph decides what to do.

Let's first define the receiver morph:

```groovy
Morph subclass: #ReceiverMorph
instanceVariableNames: ''
classVariableNames: ''
package: 'PBE-Morphic'
```

Now define the initialization method in the usual way:

```groovy
ReceiverMorph >> initialize
super initialize.
color := Color red.
bounds := 0 @ 0 extent: 200 @ 200
```

How do we decide if the receiver morph will accept or reject the dropped morph? In general, both of the morphs will have to agree to the interaction.
<figure><img src="image_140.png" /><figcaption>Figure 13.15: A ReceiverMorph and an EllipseMorph.</figcaption></figure>

The receiver does this by responding to `wantsDroppedMorph:event:`. Its first argument is the dropped morph, and the second the mouse event, so that the receiver can, for example, see if any modifier keys were held down at the time of the drop. The dropped morph is also given the opportunity to check and see if it likes the morph onto which it is being dropped, by responding to the message `wantsToBeDroppedInto:`. The default implementation of this method (in class `Morph`) answers `true`.

```
[ ReceiverMorph >> wantsDroppedMorph: aMorph event: anEvent
    ^ aMorph color = Color blue
]
```

What happens to the dropped morph if the receiving morph doesn't want it? The default behaviour is for it to do nothing, that is, to sit on top of the receiving morph, but without interacting with it. A more intuitive behavior is for the dropped morph to go back to its original position. This can be achieved by the receiver answering `true` to the message `repelsMorph:event:` when it doesn't want the dropped morph:

```
[ ReceiverMorph >> repelsMorph: aMorph event: anEvent
    ^ (self wantsDroppedMorph: aMorph event: anEvent) not
]
```

That's all we need as far as the receiver is concerned.

Create instances of `ReceiverMorph` and `EllipseMorph` in a playground:

```
[ ReceiverMorph new openInWorld;
    bounds: (100@100 corner: 200@200).
    EllipseMorph new openInWorld.
]
```

Try to drag and drop the yellow `EllipseMorph` onto the receiver. It will be rejected and sent back to its initial position.

To change this behaviour, change the color of the ellipse morph to the color blue (by sending it the message `color: Color blue;` right after `new`). Blue morphs should be accepted by the `ReceiverMorph`.
13.8 A complete example

Let's create a specific subclass of Morph, named DroppedMorph, so we can
experiment a bit more:

Morph subclass: #DroppedMorph
instanceVariableNames: ''
classVariableNames: ''
package: 'PBE-Morphic'

DroppedMorph >> initialize
super initialize.
color := Color blue.
self position: 250 @ 100

Now we can specify what the dropped morph should do when it is rejected by
the receiver; here it will stay attached to the mouse pointer:

DroppedMorph >> rejectDropMorphEvent: anEvent
| h |
h := anEvent hand.
WorldState addDeferredUIMessage: [ h grabMorph: self ].
anEvent wasHandled: true

Sending the hand message to an event answers the *hand*, an instance of *Hand-Morph* that represents the mouse pointer and whatever it holds. Here we tell the *World* that the hand should grab *self*, the rejected morph.

Create two instances of DroppedMorph, and then drag and drop them onto the receiver.

ReceiverMorph new openInWorld.
morph := (DroppedMorph new color: Color blue) openInWorld.
morph position: (morph position + (70@0)).
(DroppedMorph new color: Color green) openInWorld.

The green morph is rejected and therefore stays attached to the mouse
pointer.

13.8 A complete example

Let's design a morph to roll a die. Clicking on it will display the values of all sides of the die in a quick loop, and another click will stop the animation.

Define the die as a subclass of BorderedMorph instead of Morph, because we
will make use of the border.

BorderedMorph subclass: #DieMorph
instanceVariableNames: 'faces dieValue isStopped'
classVariableNames: ''
package: 'PBE-Morphic'

The instance variable faces records the number of faces on the die; we al-
low dice with up to 9 faces! dieValue records the value of the face that is
<figure><img src="image_141.png" /><figcaption>Figure 13.16: Creation of DroppedMorph and ReceiverMorph.</figcaption></figure>

<figure><img src="image_142.png" /><figcaption>Figure 13.17: The die in Morphic</figcaption></figure>

currently displayed, and `isStopped` is true if the die animation has stopped running. To create a die instance, we define the `faces: n` method on the `class` side of `DieMorph` to create a new die with n faces.

```ruby
DieMorph class >> faces: aNumber
    ^ self new faces: aNumber
```

The `initialize` method is defined on the instance side in the usual way; remember that `new` automatically sends `initialize` to the newly-created instance.

```ruby
DieMorph >> initialize
    super initialize.
    self extent: 50 @ 50.
    self
```
13.8 A complete example

```java
useGradientFill;
borderWidth: 2;
useRoundedCorners.
self setBorderStyle: #complexRaised.
self fillStyle direction: self extent.
self color: Color green.
dieValue := 1.
faces := 6.
isStopped := false
```

We use a few methods of BorderedMorph to give a nice appearance to the die: a thick border with a raised effect, rounded corners, and a color gradient on the visible face. We define the instance method `faces:` to check for a valid parameter as follows:

```java
DieMorph >> faces: aNumber
"Set the number of faces"
((aNumber isInteger and: [ aNumber > 0 ]) and: [ aNumber <= 9 ])
ifTrue: [ faces := aNumber ]
```

It may be good to review the order in which the messages are sent when a die is created. For instance, if we start by evaluating `DieMorph faces: 9`:

* The class method `DieMorph class >> faces:` sends `new` to `DieMorph class`.

* The method for new (inherited by `DieMorph` class from `Behavior`) creates the new instance and sends it the `initialize` message.

* The `initialize` method in `DieMorph` sets `faces` to an initial value of 6.

* `DieMorph class >> new` returns to the class method `DieMorph class >> faces:`, which then sends the message `faces: 9` to the new instance.

* The instance method `DieMorph >> faces:` now executes, setting the `faces` instance variable to 9.

Before defining `drawOn:`, we need a few methods to place the dots on the displayed face:

```java
DieMorph >> face1
^ { (0.5 @ 0.5) }

DieMorph >> face2
^{ 0.25@0.25 . 0.75@0.75 }

DieMorph >> face3
^{ 0.25@0.25 . 0.75@0.75 . 0.5@0.5 }

DieMorph >> face4
^{ 0.25@0.25 . 0.75@0.25 . 0.75@0.75 . 0.25@0.75 }
```
```
[ DieMorph >> face5
    ^{0.25@0.25 . 0.75@0.25 . 0.75@0.75 . 0.25@0.75 . 0.5@0.5}

[ DieMorph >> face6
    ^{0.25@0.25 . 0.75@0.25 . 0.75@0.75 . 0.25@0.75 . 0.25@0.5 .
        0.75@0.5}

[ DieMorph >> face7
    ^{0.25@0.25 . 0.75@0.25 . 0.75@0.75 . 0.25@0.75 . 0.25@0.5 .
        0.75@0.5 . 0.5@0.5}

[ DieMorph >> face8
    ^{0.25@0.25 . 0.75@0.25 . 0.75@0.75 . 0.25@0.75 . 0.25@0.5 .
        0.75@0.5 . 0.5@0.5 . 0.5@0.25}

[ DieMorph >> face9
    ^{0.25@0.25 . 0.75@0.25 . 0.75@0.75 . 0.25@0.75 . 0.25@0.5 .
        0.75@0.5 . 0.5@0.5 . 0.5@0.25 . 0.5@0.75}
```

These methods define collections of the coordinates of dots for each face. The coordinates are in a square of size 1x1; we will simply need to scale them to place the actual dots.

The `drawOn:` method does two things: it draws the die background with the super-send, and then draws the dots.

```
[ DieMorph >> drawOn: aCanvas
    super drawOn: aCanvas.
    (self perform: ('face', dieValue asString) asSymbol)
    do: [:aPoint | self drawDotOn: aCanvas at: aPoint]
```

The second part of this method uses the reflective capacities of Pharo. Drawing the dots of a face is a simple matter of iterating over the collection given by the `faceX` method for that face, sending the `drawDotOn:at:` message for each coordinate. To call the correct `faceX` method, we use the `perform:` method which sends a message built from a string, ('face', `dieValue` as-String) `asSymbol`. You will encounter this use of `perform:` quite regularly.

```
[ DieMorph >> drawDotOn: aCanvas at: aPoint
    aCanvas
    fillOval: (Rectangle
        center: self position + (self extent * aPoint)
        extent: self extent / 6)
    color: Color black
```

Since the coordinates are normalized to the `[0:1]` interval, we scale them to the dimensions of our die: `self extent * aPoint`.

We can already create a die instance from a playground (see result on Figure 13.18):

```
[ (DieMorph faces: 6) openInWorld.
```
<figure><img src="image_143.png" /><figcaption>**Figure 13.18:** A new die 6 with (DieMorph faces: 6) openInWorld</figcaption></figure>

<figure><img src="image_144.png" /><figcaption>**Figure 13.19:** Result of (DieMorph faces: 6) openInWorld; dieValue: 5.</figcaption></figure>

To change the displayed face, we create an accessor that we can use as `myDie`

```kotlin
[DieMorph >> dieValue: aNumber
   ((aNumber isInteger and: [aNumber > 0]) and: [aNumber <= faces])
   ifTrue: [
      dieValue := aNumber.
      self changed ]
```

Now we will use the animation system to show quickly all the faces:

```kotlin
[DieMorph >> stepTime
   ^ 100

DieMorph >> step
   isStopped ifFalse: [self dieValue: (1 to: faces) atRandom]
```

Now the die is rolling!

To start or stop the animation by clicking, we will use what we learned previously about mouse events. First, activate the reception of mouse events:

```kotlin
[DieMorph >> handlesMouseDown: anEvent
   ^ true
```
<figure><img src="image_145.png" /><figcaption>**Figure 13.20:** The die displayed with alpha-transparency</figcaption></figure>

```Flash
[DieMorph >> mouseDown: anEvent
       anEvent redButtonPressed
       ifTrue: [isStopped := isStopped not]]
```

Now the die will roll or stop rolling when we click on it.

## 13.9 More about the canvas

The `drawOn:` method has an instance of `Canvas` as its sole argument; the canvas is the area on which the morph draws itself. By using the graphics methods of the canvas you are free to give the appearance you want to a morph. If you browse the inheritance hierarchy of the `Canvas` class, you will see that it has several variants. The default variant of `Canvas` is `FormCanvas`, and you will find the key graphics methods in `Canvas` and `FormCanvas`. These methods can draw points, lines, polygons, rectangles, ellipses, text, and images with rotation and scaling.

It is also possible to use other kinds of `canvas`, for example to obtain transparent morphs, more graphics methods, antialiasing, and so on. To use these features you will need an `AlphaBlendingCanvas` or a `BalloonCanvas`. But how can you obtain such a `canvas` in a `drawOn:` method, when `drawOn:` receives an instance of `FormCanvas` as its argument? Fortunately, you can transform one kind of `canvas` into another.

To use a `canvas` with a 0.5 alpha-transparency in `DieMorph`, redefine `drawOn:` like this:

```Flash
[DieMorph >> drawOn: aCanvas
    | theCanvas |
    theCanvas := aCanvas asAlphaBlendingCanvas: 0.5.
    super drawOn: theCanvas.
    (self perform: ('face', dieValue asString) asSymbol)
    do: [:aPoint | self drawDotOn: theCanvas at: aPoint]]
```

That's all you need to do!
## 13.10 Chapter summary

Morphic is a graphical framework in which graphical interface elements can be dynamically composed.

* You can convert an object into a morph and display that morph on the screen by sending it the messages asMorph openInWorld.

* You can manipulate a morph by meta-clicking on it and using the handles that appear. (Handles have help balloons that explain what they do.)

* You can compose morphs by embedding one onto another, either by drag and drop or by sending the message addMorph:.

* You can subclass an existing morph class and redefine key methods, like initialize and drawOn:.

* You can control how a morph reacts to mouse and keyboard events by redefining the methods handlesMouseDown:, handlesMouseOver:, etc.

* You can animate a morph by defining the methods step (what to do) and stepTime (the number of milliseconds between steps).
<figure><img src="image_146.png" /></figure>
CHAPTER 14

Seaside by example

Seaside is a framework for building web applications in Smalltalk, originally developed by Avi Bryant and Julian Fitzell in 2002. Once mastered, Seaside makes web applications almost as easy to write as desktop applications. Seaside is really interesting for developing fast complex applications. For example http://allstocker.com is a Seaside commercial applications or the Quuve, FinWorks and CableExpertise application from http://www.pharo.org/success have been developed in Seaside.

Seaside is unusual in that it is thoroughly object-oriented: there are no HTML templates, no complicated control flows through web pages, and no encoding of state in URLs. Instead, you just send messages to objects. What a nice idea!

14.1 Why do we need Seaside?

Modern web applications try to interact with the user in the same way as desktop applications: they ask the user questions and the user responds, usually by filling in a form or clicking a button. But the web works the other way around: the user's browser makes a request of the server, and the server responds with a new web page. So web application development frameworks have to cope with a host of problems, chief among them being the management of this *inverted* control flow. Because of this, many web applications try to forbid the use of the browser's *Back* button due to the difficulty of keeping track of the state of a session. Expressing non-trivial control flows across multiple web pages is often cumbersome, and multiple control flows can be difficult or impossible to express.

Seaside is a component-based framework that makes web development easier in several ways. First, control flow can be expressed naturally using message
sends. Seaside keeps track of which web page corresponds to which point
in the execution of the web application. This means that the browser's *Back*
button works correctly.

Second, state is managed for you. As the developer, you have the choice of
enabling backtracking of state, so that navigation *Back* in time will undo side-
effects. Alternatively, you can use the transaction support built into Seaside to
prevent users from undoing permanent side-effects when they use the back
button. You do not have to encode state information in the URL — this too is
managed automatically for you.

Third, web pages are built up from nested components, each of which can
support its own, independent control flow. There are no HTML templates —
instead valid HTML is generated programmatically using a simple Smalltalk-
based protocol. Seaside supports Cascading Style Sheets (CSS), so content and
layout are cleanly separated.

Finally, Seaside provides a convenient web-based development interface, mak-
ing it easy to develop applications iteratively, debug applications interactively,
and recompile and extend applications while the server is running.

## 14.2 Getting started

### The Seaside community

The Seaside.st website (http://www.seaside.st) contains many Seaside-related
resources, including downloads, documentation and tutorials. (Keep in mind
that Seaside has evolved considerably over the years, and not all available
material refers to the latest version.) There are also several active mailing
lists, which you can find at http://www.seaside.st/community/mailinglist.

In addition, the Wiki on the Seaside GitHub repository (https://github.com/seasidest/seaside/wiki) provides some crucial documentation, including the Release Notes for each version of Seaside.

### Installing Seaside using the one-click experience image

The easiest way to get started is to download the Seaside One-Click Ex-
perience 3.1 from the Pharo Downloads section of the Seaside web site
(http://www.seaside.st/download/pharo). This is a prepackaged version of the
latest stable version of Seaside for Mac OSX, Linux and Windows, built on
Pharo 4. The current latest Seaside version is 3.2. These are full Pharo distribu-
tions, which include the Pharo VM as well as a development image with many
Seaside-related packages preloaded, and a helpful Seaside control panel that
starts when you open the image.

Download and launch the Seaside One-Click image (feel free to refer to the
Getting Started section of Chapter: A Quick Tour of Pharo for an in-depth
<figure><img src="image_147.png" /><figcaption>Figure 14.1: Start up the Seaside One-Click Experience image.</figcaption></figure>

discussion of launching Pharo images). Once started, you should see something similar to Figure 14.1 - a familiar Pharo development environment with some windows pre-opened, such as welcome messages as well as a Seaside Control Panel.

## Starting the Seaside server

The easiest way to start and stop the Seaside web server is through the Seaside Control Panel. If you're using the Seaside One-Click Experience image, it should already be open (and running a server adapter) when you open the image for the first time. You can manually open it at any time, however, by evaluating `WAPhoarServerAdapterSpecBrowser open`.

Right-clicking on the top pane of the Seaside Control Panel lets you add new server adapters. For example, you can add a `ZnZincServerAdaptor`, specify a port number, then start it using the Start button on the control panel, which launches a new Seaside server that listens on that port.

```
ZnZincServerAdaptor startOn: 8080. "start on port 8080"
ZnZincServerAdaptor stop.
```

You can also start and stop the Seaside web server from a playground, by sending the `startOn:` and `stop` messages to your server adapter of choice.
## The Seaside welcome page

Once the Seaside server is running, navigate to http://localhost:8080/ in your web browser. You should see a web page that looks like Figure 14.2.

The Welcome page contains links to some sample Seaside applications. It also links to various documents and resources, and (in the sidebar) links to the Configuration and Browse applications that allow you to interact with Seaside applications registered in your image.

Let's look at one of the example applications that demonstrates the Counter component: click on the Counter link.

This page is a small Seaside application: it displays a counter component that can be incremented or decremented by clicking on the ++ and -- links (see Figure 14.3).

Play with the counter by clicking on these links. Use your browser's Back button to go back to a previous state, and then click on ++ again. Notice how the counter is correctly incremented with respect to the currently displayed state, rather than the state that the counter was in when you started using the Back button.

Notice the toolbar at the bottom of the web page in Figure 14.2. Seaside supports a notion of sessions to keep track of the state of the application for different users. New Session will start a new session on the counter application. Configure allows you to configure the settings of your application through a web interface. (To close the Configure view, click on the x in the top right corner.) Halos provides a way to explore the state of the application running on the Seaside server. Profile and Memory provide detailed information about the run-time performance of the application. XHTML can be used to validate the generated web page, but works only when the web page is publicly accessible from the Internet, because it uses the W3C validation service.

## Single components

Seaside applications are built up from pluggable components. In fact, components are ordinary Smalltalk objects. The only thing that is special about them is that they are instances of classes that inherit from the Seaside framework class WAComponent. We can explore components and their classes from the Pharo image, or directly from the web interface using halos.

Click on the Halos link at the bottom of the page to toggle on halo functionality. You'll see a number of nested components each with their own halo icons, including the Counter component (you may have to scroll down a bit to reach it), like the one seen in Figure 14.4.

At the top left of the component, the text WACounter tells us the class of the Seaside component that implements its behavior. Next to this are three clickable icons. The first is the Class Browser (the notepad with pencil icon),
<figure><img src="image_148.png" /><figcaption>Figure 14.2: The Seaside Welcome application at http://localhost:8080/.</figcaption></figure>

## Example: Counter

[ go back ]

The counter is an example of a very simple Seaside component. It increments and decrements a number by clicking on a link. Test the example below by clicking on the "++" and "--" links:

<figure><img src="image_149.png" /><figcaption>Figure 14.3: The counter.</figcaption></figure>
<figure><img src="image_150.png" /><figcaption>**Figure 14.4:** Halos.</figcaption></figure>

<figure><img src="image_151.png" /><figcaption>**Figure 14.5:** Debugging the running Counter application in the Pharo image.</figcaption></figure>

which opens up a (web-based) Seaside class browser on this component's class. The second is the **Object Inspector** (notepad with magnifying glass icon), which opens a web-based object inspector on the actual **WACounter** instance. The third is the **CSS Style Manager** (the coloured circles icon), opens a Seaside view to display the CSS style sheet for this component.

At the top right of the component, the **Render / Source** links let you toggle between the Rendered and (formatted) Source views of the component's HTML source code. Experiment with all of these links. Note that the `++` and `-` links are also active in the source view.

The Seaside Class Browser and Object Inspector can be very convenient when the server is running on another computer, especially when the server does not have a display, or if it is in remote place. However, when you are first developing a Seaside application, the server will be running locally, and it is easy to use the ordinary Pharo development tools in the server image.

Using the Object Inspector link in the web browser, open an inspector on the underlying Pharo counter object, type `self halt` and click the `doIt` button.

The form submits, and the browser will hang, spinning. Now switch to the Pharo Seaside image. You should see a pre-debugger window (Figure 14.5) showing a WACounter object executing a halt. Examine this execution in the debugger, and then Proceed. Go back to the web browser and notice that the
<figure><img src="image_152.png" /><figcaption>Figure 14.6: Independent subcomponents.</figcaption></figure>

Counter application is running again.

## Multiple components

Seaside components can be instantiated multiple times and in different contexts.

Now, point your web browser to http://localhost:8080/examples/multicounter.

You will see a simple application composed of a number of independent instances of the WACounter component, nested inside a WAMultiCounter. Increment and decrement several of the counters. Verify that they behave correctly even if you use the *Back* button. Toggle the halos to see how the application is built out of nested components. Use the Seaside class browser to view the implementation of WAMultiCounter. You should see two methods on the class side (description, and initialize) and three on the instance side (children, initialize, and renderContentOn:). Note that an application is simply a component that is willing to be at the root of the component containment hierarchy; this willingness is indicated by defining a class-side method canBeRoot to answer true.

You can use the Seaside web interface to configure, copy or remove individual applications (which are root-level components). Try making the following configuration change.

Point your web browser to http://localhost:8080/config.

If you are asked for a login, supply the default login and password (admin and seaside). You can see a list of a registered applications and dispatchers.
<figure><img src="image_153.png" /><figcaption>Figure 14.7: Add a new application.</figcaption></figure>

Change into the examples dispatcher list by clicking on the link on the left side. With the buttons at the topbar, we can add new request handlers, open the current, copy, remove or set it as the default page. We want to add a new example application. Select Add, enter the name `counter2` and choose the type `Application`, click OK (see Figure 14.7).

On the next screen, set the Root Component to `WACounter`, apply the changes (Figure 14.8).

Now we have a new counter installed at http://localhost:8080/examples/counter2. Use the same `Remove-button` in the configuration interface to remove this entry point.

Seaside operates in two modes: *development mode*, which is what we have seen so far, and *deployment mode*, in which the toolbar is not available.

You can put a Seaside Application into deployment mode by removing the inherited Root Decoration Class (again, see Figure 14.8).

Alternatively, you can disable the development toolbar for all new applications by evaluating the code:

```javascript
AAdmin applicationDefaults
  removeParent: WADevelopmentConfiguration instance
```

If you want to enable the password protection, you need to add the `WAAuth-Configuration` in the `Inherited Configuration`. Choose `WAAuthConfiguration` from the list of possible parents, after adding this configuration, you can define the `Login` and `Password` setting.

## 14.3 Seaside components

As we mentioned in the previous section, Seaside applications are built out of components. Let's take a closer look at how Seaside works by implementing
<figure><img src="image_154.png" /><figcaption>Figure 14.8: Configure the new application.</figcaption></figure>
<figure><img src="image_155.png" /><figcaption>**Figure 14.9: Hello World in Seaside.**</figcaption></figure>

the *Hello World* component.

Every Seaside component should inherit directly or indirectly from `WAComponent`, as shown in Figure 14.10. (Incidentally, the 'WA' prefix often used in Seaside code stands for 'Web Application'.)

Define a subclass of `WAComponent` called `WAHelloWorld`.

Components must know how to render themselves. Usually this is done by implementing the method `renderContentOn:`, which gets as its argument an instance of `WAHtmlCanvas`, which knows how to render HTML.

Implement the following method, and put it in a protocol called `rendering`:

```
WAHelloWorld >> renderContentOn: html
html text: 'hello world'
```

Now we must inform Seaside that this component is willing to be a standalone application.

Implement the following method on the class side of `WAHelloWorld`.

```
WAHelloWorld class >> canBeRoot
^ true
```

We are almost done!

Point your web browser at http://localhost:8080/config, add a new entry point called `hello`, and set its root component to be `WAHelloWorld`.

Now navigate to http://localhost:8080/hello. That's it! You should see a web page similar to Figure 14.9.
<figure><img src="image_156.png" /><figcaption>**Figure 14.10:** The WACounter class, which implements the *counter* application. Methods with underlined names are on the class-side; those with plain-text names are on the instance side.</figcaption></figure>

## State backtracking and the Counter application

The *counter* application is only slightly more complex than the *hello world* application.

The class WACounter is a standalone application, so WACounter class must answer true to the canBeRoot message. It must also register itself as an application; this is done in its class-side initialize method, as shown in Figure 14.10.

WACounter defines two methods, increase and decrease, which will be triggered from the ++ and -- links on the web page. It also defines an instance variable count to record the state of the counter. However, we also want Seaside to synchronize the counter with the browser page: when the user clicks on the browser's Back button, we want seaside to backtrack the state of the WACounter object. Seaside includes a general mechanism for backtracking, but each application has to tell Seaside which parts of its state to track.

A component enables backtracking by implementing the states method on the instance side: states should answer an array containing all the objects to be tracked. In this case, the WACounter object adds itself to Seaside's table of backtrackable objects by returning Array with: self.

**Backtracking caveat** There is a subtle but important point to watch for when declaring objects for backtracking. Seaside tracks state by making a copy of
all the objects declared in the states array. It does this using a `WASnapshot` object; `WASnapshot` is a subclass of `IdentityDictionary` that records the objects to be tracked as keys and shallow copies of their state as values. If the state of an application is backtracked to a particular snapshot, the state of each object entered into the snapshot dictionary is overwritten by the copy saved in the snapshot.

Here is the point to watch out for: In the case of `WACounter`, you might think that the state to be tracked is a number — the value of the count instance variable. However, having the `states` method answer `Array with: count` won't work. This is because the object named by `count` is an integer, and integers are immutable. The `increase` and `decrease` methods don't change the state of the object 0 into 1 or the object 3 into 2. Instead, they make `count` hold a different integer: every time the `count` is incremented or decremented, the object named by `count` is *replaced* by another. This is why `WACounter>>states` must return `Array with: self`. When the state of a `WACounter` object is replaced by a previous state, the *value* of each of the instance variable in the object is replaced by a previous value; this correctly replaces the current value of `count` by a prior value.

## 14.4 Rendering HTML

The purpose of a web application is to create, or *render*, web pages. As we mentioned in Section 14.3, each Seaside component is responsible for rendering itself. So, let's start our exploration of rendering by seeing how the counter component renders itself.

### Rendering the Counter

The rendering of the counter is relatively straightforward; the code is shown in Figure 14.10. The current value of the counter is displayed as an HTML heading, and the increment and decrement operations are implemented as HTML anchors (that is, links) with callbacks to blocks that will send `increase` and `decrease` to the counter object.

We will have a closer look at the rendering protocol in a moment. But before we do, let's have a quick look at the multi-counter.

### From Counter to MultiCounter

`WAMultiCounter`, shown in Figure 14.11 is also a standalone application, so it overrides `canBeRoot` to answer true. In addition, it is a *composite* component, so Seaside requires it to declare its children by implementing a method `children` that answers an array of all the components it contains. It renders itself by rendering each of its subcomponents, separated by a horizontal rule. Aside
<figure><img src="image_157.png" /><figcaption>Figure 14.11: WAMultiCounter.</figcaption></figure>

from instance and class-side initialization methods, there is nothing else to the multi-counter!

## More about rendering HTML

As you can see from these examples, Seaside does not use templates to generate web pages. Instead it generates HTML programmatically. The basic idea is that every Seaside component should override the method renderContentOn:; this message will be sent by the framework to each component that needs to be rendered. This renderContentOn: message will have an argument that is an HTML canvas onto which the component should render itself. By convention, the HTML canvas parameter is called html. An HTML canvas is analogous to the graphics canvas used by Morphic (and most other drawing frameworks) to abstract away from the device-dependent details of drawing.

Here are some of the most basic rendering methods:

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

The message render: anyObject can be sent to an HTML canvas to render anyObject; it is normally used to render subcomponents. anyObject will itself be sent the message renderContentOn: this is what happens in the multi-counter (see Figure 14.11).

## Using brushes

A canvas provides a number of brushes that can be used to render (i.e., paint) content on the canvas. There are brushes for every kind of HTML element — paragraphs, tables, lists, and so on. To see the full protocol of brushes and convenience methods, you should browse the class WACanvas and its subclasses. The argument to renderContentOn: is actually an instance of the subclass WARender.
<figure><img src="image_159.png" /><figcaption>Figure 14.12: RenderingDemo.</figcaption></figure>

We have already seen the following brush used in the counter and multi-
counter examples:

[html horizontalRule.]

In Figure 14.12 we can see the output of many of the basic brushes offered
by Seaside. (The source code for method SeasideDemo >> renderContentOn:
defined below is in the package PBE-SeasideDemo in the project http://www.
squeaksource.com/PharoByExample.) The root component SeasideDemo sim-
ply renders its subcomponents, which are instances of SeasideHtmlDemo,
SeasideFormDemo, SeasideEditCallDemo and SeasideDialogDemo, as shown
below.
```
SeasideDemo >> renderContentOn: html
html heading: 'Rendering Demo'.
html heading
    level: 2;
    with: 'Rendering basic HTML: '.
html div
    class: 'subcomponent';
    with: htmlDemo.
"render the remaining components ..."
```

Recall that a root component must always declare its children, or Seaside will refuse to render them.

```
SeasideDemo >> children
    ^ { htmlDemo . formDemo . editDemo . dialogDemo }
```

Notice that there are two different ways of instantiating the heading brush. The first way is to set the text directly by sending the message `heading:`. The second way is to instantiate the brush by sending `heading`, and then to send a cascade of messages to the brush to set its properties and render it. Many of the available brushes can be used in these two ways.

**Important** If you send a cascade of messages to a brush including the message `with:`, then `with` should be the *final* message. `with`: both sets the content and renders the result.

In method `renderContentOn:` above, the first heading is at level 1, since this is the default. We explicitly set the level of the second heading to 2. The sub-component is rendered as an HTML `div` with the CSS class `subcomponent`. (More on CSS in Section 14.5.) Also note that the argument to the `with:` keyword message need not be a literal string: it can be another component, or even — as in the next example — a block containing further rendering actions.

The `SeasideHtmlDemo` component demonstrates many of the most basic brushes. Most of the code should be self-explanatory.

```
SeasideHtmlDemo >> renderContentOn: html
    self renderParagraphsOn: html.
    self renderListsAndTablesOn: html.
    self renderDivsAndSpansOn: html.
    self renderLinkWithCallbackOn: html
```

It is common practice to break up long rendering methods into many helper methods, as we have done here.

A word of advice: Don't put all your rendering code into a single method.

Instead, split it into helper methods named using the pattern `render*On:`. All rendering methods go in the `rendering` protocol. Don't send `renderContentOn: from your own code, use render: instead`.
Look at the following code. The first helper method, `SeasideHtmlDemo>>renderParagraphsOn:`, shows you how to generate HTML paragraphs, plain and emphasized text, and images. Note that in Seaside simple elements are rendered by specifying the text they contain directly, whereas complex elements are specified using blocks. This is a simple convention to help you structure your rendering code.

```html
SeasideHtmlDemo >> renderParagraphsOn: html
html paragraph: 'A plain text paragraph.'.
html paragraph: [
html
  text: 'A paragraph with plain text followed by a line break. ';
  break;
  emphasis: 'Emphasized text ';
  text: 'followed by a horizontal rule.';
  horizontalRule;
  text: 'An image URI: '.
html image
  url: self squeak_image_url;
  width: '50']
```

The next helper method, `SeasideHtmlDemo>>renderListsAndTablesOn:`, shows you how to generate lists and tables. A table uses two levels of blocks to display each of its rows and the cells within the rows.

```html
SeasideHtmlDemo >> renderListsAndTablesOn: html
html orderedList: [
html listItem: 'An ordered list item'].
html unorderedList: [
html listItem: 'An unordered list item'].
html table: [
html tableRow: [
html tableData: 'A table with one data cell.']]
```

The next example shows how we can specify class or id attributes for div and span elements (for use with CSS). Of course, the messages `class:` and `id:` can also be sent to the other brushes, not just to div and span. The method `SeasideDemoWidget>>style` defines how these HTML elements should be displayed (see Section 14.5).

```html
SeasideHtmlDemo >> renderDivsAndSpansOn: html
html div
  id: 'author';
with: [
  html text: 'Raw text within a div with id ''author''. '.
  html span
    class: 'highlight';
    with: 'A span with class ''highlight''.']
```

Finally we see a simple example of a link, created by binding a simple callback to an anchor (i.e., a link). Clicking on the link will cause the subsequent text
to toggle between true and false by toggling the instance variable ` toggleValue`.

```python
SeasideHtmlDemo >> renderLinkWithCallbackOn: html
html paragraph: [
    html text: 'An anchor with a local action: '.
    html span with: [
        html anchor
            callback: [ toggleValue := toggleValue not];
            with: ' toggle boolean: '].
    html space.
    html span
        class: 'boolean';
        with: toggleValue ]
```

Note that actions should appear only in callbacks.

The code executed while rendering should not change the state of the application!

## Forms

Forms are rendered just like the other examples that we have already seen. Here is the code for the SeasideFormDemo component in Figure 14.12.

```python
SeasideFormDemo >> renderContentOn: html
| radioGroup |
html heading: heading.
html form: [
    html span: 'Heading: '.
    html textInput on: #heading of: self.
    html select
        list: self colors;
        on: #color of: self.
    radioGroup := html radioGroup.
    html text: 'Radio on:'.
    radioGroup radioButton
        selected: radioOn;
        callback: [ radioOn := true].
    html text: 'off:'.
    radioGroup radioButton
        selected: radioOn not;
        callback: [ radioOn := false].
    html checkbox on: #checked of: self.
    html submitButton
        text: 'done' ]
```

Since a form is a complex entity, it is rendered using a block. Note that all the state changes happen in the callbacks, not as part of the rendering.
There is one Seaside feature used here that is worth special mention, namely the message `on:of:`. In the example, this message is used to bind a text input field to the variable `heading`. Anchors and buttons also support this message. The first argument is the name of an instance variable for which accessors have been defined; the second argument is the object to which this instance variable belongs. Both observer (`heading`) and mutator (`heading:`) accessor messages must be understood by the object, with the usual naming convention. In the case of a text input field, this saves us the trouble of having to define a callback that updates the field as well as having to bind the default contents of the HTML input field to the current value of the instance variable. Using `on: #heading of: self`, the `heading` variable is updated automatically whenever the user updates the text input field.

The same message is used twice more in this example, to cause the selection of a colour on the HTML form to update the `color` variable, and to bind the result of the checkbox to the `checked` variable. Many other examples can be found in the functional tests for Seaside. Have a look at the package `Seaside-Tests-Functional`, or just point your browser to http://localhost:8080/tests/functional. Select `WAInputPostFunctionalTest` and click on the `Restart` button to see most of the features of forms.

Don't forget, if you toggle `Halos`, you can browse the source code of the examples directly using the Seaside class browser.

## 14.5 CSS: Cascading style sheets

Cascading Style Sheets (http://www.w3.org/Style/CSS/), or CSS for short, are a standard way for web applications to separate style from content. Seaside relies on CSS to avoid cluttering your rendering code with layout considerations.

You can set the CSS style sheet for your web components by defining the `method style`, which should return a string containing the CSS rules for that component. The styles of all the components displayed on a web page are joined together, so each component can have its own style. A better approach can be to define an abstract class for your web application that defines a common style for all its subclasses.

Actually, for deployed applications, it is more common to define style sheets as external files. This way the look and feel of the component is completely separate from its functionality. (Have a look at `WAFileLibrary`, which provides a way to serve static files without the need for a standalone server.)

If you already are familiar with CSS, then that's all you need to know. Otherwise, read on for a very brief introduction to CSS.

Instead of directly encoding display attributes in the paragraph and text elements of your web pages, CSS lets you define different *classes* of elements, and place all display considerations in a separate style sheet.
To put it another way, a CSS style sheet consists of a set of rules that specify how to format given HTML elements. Each rule consists of two parts. There is a *selector* that specifies which HTML elements the rule applies to, and there is a *declaration* which sets a number of attributes for that element.

```css
SeasideDemoWidget >> style
^
body {
    font: 10pt Arial, Helvetica, sans-serif, Times New Roman;
}
h2 {
    font-size: 12pt;
    font-weight: normal;
    font-style: italic;
}
table { border-collapse: collapse; }
td {
    border: 2px solid #CCCCCC;
    padding: 4px;
}
#author {
    border: 1px solid black;
    padding: 2px;
    margin: 2px;
}
.subcomponent {
    border: 2px solid lightblue;
    padding: 2px;
    margin: 2px;
}
.highlight { background-color: yellow; }
 boolean { background-color: lightgrey; }
 .field { background-color: lightgrey; }
```

The previous method illustrates a simple style sheet for the rendering demo shown earlier in Figure 14.12. The first rule specifies a preference for the fonts to use for the body of the web page. The next few rules specify properties of second-level headings (h2), tables (table), and table data (td).

The remaining rules have selectors that will match HTML elements that have the given class or id attributes. CSS selectors for class attributes start with a `.` and those for id attributes with `#`. The main difference between class and id attributes is that many elements may have the same class, but only one element may have a given id (i.e., an *identifier*). So, whereas a class attribute, such as `highlight`, may occur multiple times on any page, an id must identify a *unique* element on the page, such as a particular menu, the modified date, or author. Note that a particular HTML element may have multiple classes, in which case all the applicable display attributes will be applied in sequence.
Selector conditions may be combined, so the selector div.subcomponent will only match an HTML element if it is both a div and it has a class attribute equal to subcomponent.

It is also possible to specify nested elements, though this is seldom necessary. For example, the selector p span will match a span within a paragraph but not within a div.

There are numerous books and web sites to help you learn CSS. For a dramatic demonstration of the power of CSS, we recommend you to have a look at the CSS Zen Garden (http://www.csszengarden.com/), which shows how the same content can be rendered in radically different ways simply by changing the CSS style sheet.

## 14.6 Managing control flow

Seaside makes it particularly easy to design web applications with non-trivial control flow. There are basically two mechanisms that you can use:

1. A component can *call* another component by sending `caller call: callee`. The caller is temporarily replaced by the callee, until the callee returns control by sending `answer:`. The caller is usually `self`, but could also be any other currently visible component.

2. A workflow can be defined as a *task*. This is a special kind of component that subclasses `WATask` (instead of `WAComponent`). Instead of defining `renderContentOn:`, it defines no content of its own, but rather defines a `go` method that sends a series of `call:` messages to activate various subcomponents in turn.

### Call and answer

Call and answer are used to realize simple dialogues.

There is a trivial example of `call:` and `answer:` in the rendering demo of Figure 14.12. The component `SeasideEditCallDemo` displays a text field and an edit link. The callback for the edit link calls a new instance of `SeasideEditAnswerDemo` initialized to the value of the text field. The callback also updates this text field to the result which is sent as an answer.

(We underline the `call:` and `answer:` sends to draw attention to them.)

```
SeasideEditCallDemo >> renderContentOn: html
```

html span

class: 'field';

with: self text.

html space.

html anchor

callback: [self text: (self call: (SeasideEditAnswerDemo new text: self text))];

with: 'edit'
What is particularly elegant is that the code makes absolutely no reference to the new web page that must be created. At run-time, a new page is created in which the `SeasideEditCallDemo` component is replaced by a `SeasideEditAnswerDemo` component; the parent component and the other peer components are untouched.

It is important to keep in mind that `call:` and `answer:` should never be used while rendering. They may safely be sent from within a callback, or from within the `go` method of a task.

The `SeasideEditAnswerDemo` component is also remarkably simple. It just renders a form with a text field. The submit button is bound to a callback that will answer the final value of the text field.

```html
SeasideEditAnswerDemo >> renderContentOn: html
html form: [
html textInput
    on: #text of: self.
html submitButton
    callback: [ self answer: self text ];
    text: 'ok'.
]
```

That's it.

Seaside takes care of the control flow and the correct rendering of all the components. Interestingly, the `Back` button of the browser will also work just fine (though side effects are not rolled back unless we take additional steps).

## Convenience methods

Since certain call-answer dialogues are very common, Seaside provides some convenience methods to save you the trouble of writing components like `SeasideEditAnswerDemo`. The generated dialogues are shown in Figure 14.13. We can see these convenience methods being used within `Seaside-DialogDemo>>renderContentOn`:

The message `request:` performs a call to a component that will let you edit a text field. The component answers the edited string. An optional label and default value may also be specified.

```html
SeasideDialogDemo >> renderContentOn: html
html anchor
    callback: [ self request: 'edit this' label: 'done' default: 'some text' ];
    with: 'self request:'.
...
```

The message `inform:` calls a component that simply displays the argument message and waits for the user to click `Ok`. The called component just returns `self`.
<figure><img src="image_160.png" /><figcaption>**Figure 14.13:** Some standard dialogs.</figcaption></figure>

```javascript
...
html space.
html anchor
    callback: [ self inform: 'yes!' ];
    with: 'self inform:'.
...
```

The message confirm: asks a question and waits for the user to select either Yes or No. The component answers a boolean, which can be used to perform further actions.

```javascript
...
html space.
html anchor
    callback: [
        (self confirm: 'Are you happy?')
        ifTrue: [ self inform: ':-)' ]
        ifFalse: [ self inform: ':-(' ]
    ];
    with: 'self confirm:'.
```

A few further convenience methods, such as `chooseFrom:caption:`, are defined in the convenience protocol of `WAComponent`.

## Tasks

A task is a component that subclasses `WATask`. It does not render anything itself, but simply calls other components in a control flow defined by implementing the method `go`.

`WAConvenienceTest` is a simple example of a task defined in the package `Seaside-Tests-Functional`. To see its effect, just point your browser to `http:`
<figure><img src="image_161.png" /><figcaption>**Figure 14.14:** A simple task.</figcaption></figure>

//localhost:8080/tests/functional, select WAFlowConvenienceFunctionalTest and click Restart.

```kotlin
WAFlowConvenienceFunctionalTest >> go
[ self chooseCheese.
  self confirmCheese ] whileFalse.
self informCheese
```

This task calls in turn three components. The first, generated by the convenience method chooseFrom: caption:, is a WAChoiceDialog that asks the user to choose a cheese.

```kotlin
WAFlowConvenienceFunctionalTest >> chooseCheese
cheese := self
chooseFrom: #('Greyerzer' 'Tilsiter' 'Sbrinz')
caption: 'What''s your favorite Cheese?'.
cheese isNil ifTrue: [ self chooseCheese ]
```

The second is a WAYesOrNoDialog to confirm the choice (generated by the convenience method confirm:).

```kotlin
WAFlowConvenienceFunctionalTest >> confirmCheese
^self confirm: 'Is ', cheese, ' your favorite cheese?'
```

Finally a WAFormDialog is called (via the convenience method inform:).

```kotlin
WAFlowConvenienceFunctionalTest >> informCheese
self inform: 'Your favorite cheese is ', cheese, '.'
```

The generated dialogues are shown in Figure 14.14.

## Transactions

We saw in Section 14.3 that Seaside can keep track of the correspondence between the state of components and individual web pages by having components register their state for backtracking: all that a component need do
<figure><img src="image_162.png" /><figcaption>**Figure 14.15:** The Sushi Store.</figcaption></figure>

is implement the method states to answer an array of all the objects whose state must be tracked.

Sometimes, however, we do not want to backtrack state: instead we want to prevent the user from accidentally undoing effects that should be permanent. This is often referred to as "the shopping cart problem". Once you have checked out your shopping cart and paid for the items you have purchased, it should not be possible to go Back with the browser and add more items to the shopping cart!

Seaside allows you to enforce restriction this by defining a task within which certain actions are grouped together as *transactions*. You can backtrack within a transaction, but once a transaction is complete, you can no longer go back to it. The corresponding pages are *invalidated*, and any attempt to go back to them will cause Seaside to generate a warning and redirect the user to the most recent valid page.

The Seaside *Sushi Store* is a sample application that illustrates many of the features of Seaside, including *transactions*. This application is bundled with your installation of Seaside, so you can try it out by pointing your browser at http://localhost:8080/seaside/examples/store. (If you cannot find it in your image, there is a version of the sushi store available on SqueakSource from http://www.squeaksource.com/SeasideExamples/.)

The *sushi store* supports the following workflow:

* Visit the store.

* Browse or search for sushi.

* Add sushi to your shopping cart.

* Checkout.

* Verify your order.
* Enter shipping address.

* Verify shipping address.

* Enter payment information.

* Your fish is on its way!

If you toggle the halos, you will see that the top-level component of the sushi store is an instance of `WAStore`. It does nothing but render the title bar, and then it renders `task`, an instance of `WAStoreTask`.

```html
WAStore >> renderContentOn: html
  "... render the title bar ..."
html div id: 'body'; with: task
```

`WAStoreTask` captures this workflow sequence. At a couple of points it is critical that the user not be able to go back and change the submitted information.

Purchase some sushi and then use the `Back` button to try to put more sushi into your cart.

You will get the message *That page has expired*.

Seaside lets the programmer say that a certain part of a workflow acts like a transaction: once the transaction is complete, the user cannot go back and undo it. This is done by sending `isolate`: to a task with the transactional block as its argument. We can see this in the sushi store workflow as follows:

```html
WAStoreTask >> go
| shipping billing creditCard |
cart := WAStoreCart new.
self isolate:
    [[ self fillCart.
      self confirmContentsOfCart ]
      whileFalse ].
self isolate:
    [ shipping := self getShippingAddress.
billing := (self useAsBillingAddress: shipping)
        ifFalse: [ self getBillingAddress ]
        ifTrue: [ shipping ].
creditCard := self getPaymentInfo.
self shipTo: shipping billTo: billing payWith: creditCard ].
self displayConfirmation.
```

Here we see quite clearly that there are two transactions. The first fills the cart and closes the shopping phase. (The helper methods such as `fillCart` take care of instantiating and calling the right subcomponents.) Once you have confirmed the contents of the cart you cannot go back without starting a new session. The second transaction completes the shipping and payment data. You can navigate back and forth within the second transaction until you
confirm payment. However, once both transactions are complete, any attempt
to navigate back will fail.

Transactions may also be nested. A simple demonstration of this is found in
the class WANestedTransaction. The first isolate: takes as argument a block
that contains another, nested isolate:

```python
WANestedTransaction >> go
self inform: 'Before parent txn'.
self isolate:
    [self inform: 'Inside parent txn'.
     self isolate: [self inform: 'Inside child txn'].
     self inform: 'Outside child txn'].
self inform: 'Outside parent txn'
```

Go to http://localhost:8080/tests/functionals, select WATransactionTest and
click on Restart. Try to navigate back and forth within the parent and child
transaction by clicking the Back button and then clicking Ok. Note that as soon
as a transaction is complete, you can no longer go back inside the transaction
without generating an error upon clicking Ok.

## 14.7 A complete tutorial example

Let's see how we can build a complete Seaside application from scratch. (The
exercise should take at most a couple of hours. If you prefer to just look at
the completed source code, you can grab it from the SqueakSource project
http://www.squeaksource.com/PharoByExample. The package to load is PBE-
SeasideRPN. The tutorial that follows uses slightly different class names so
that you can compare your implementation with ours.) We will build a RPN
(Reverse Polish Notation) calculator as a Seaside application that uses a simple
stack machine as its underlying model. Furthermore, the Seaside interface
will let us toggle between two displays — one which just shows us the current
value on top of the stack, and the other which shows us the complete state of
the stack. The calculator with the two display options is shown in Figure 14.16.

We begin by implementing the stack machine and its tests.

First, Define a new class called MyStackMachine with an instance variable
contents initialized to a new OrderedCollection.

```python
MyStackMachine >> initialize
super initialize.
contents := OrderedCollection new.
```

The stack machine should provide operations to push: and pop values, view
the top of the stack, and perform various arithmetic operations to add, sub-
tract, multiply and divide the top values on the stack.

Write some tests for the stack operations and then implement these opera-
tions. Here is a sample test:
14.7 A complete tutorial example

<figure><img src="image_163.png" /><figcaption>Figure 14.16: RPN calculator and its stack machine.</figcaption></figure>

```python
MyStackMachineTest >> testDiv
stack
    push: 3;
    push: 4;
    div.
self assert: stack size = 1.
self assert: stack top = (4/3).
```

You might consider using some helper methods for the arithmetic operations to check that there are two numbers on the stack before doing anything, and raising an error if this precondition is not fulfilled. (It's a good idea to use `Object>>assert:` to specify the preconditions for an operation. This method will raise an `AssertionFailure` if the user tries to use the stack machine in an invalid state.) If you do this, most of your methods will just be one or two lines long.

You might also consider implementing `MyStackMachine>>printOn:` to make it easier to debug your stack machine implementation with the help of an object inspector. (Hint: just delegate printing to the `contents` variable.)

Complete the `MyStackMachine` by writing operations `dup` (push a duplicate of the top value onto the stack), `exch` (exchange the top two values), and `rotUp` (rotate the entire stack contents up — the top value will move to the bottom).

Now we have a simple stack machine implementation. We can start to implement the Seaside RPN Calculator.

We will make use of 5 classes:

1. `MyRPNWidget` — this should be an abstract class that defines the common CSS style sheet for the application, and other common behavior for the components of the RPN calculator. It is a subclass of `WAComponent` and the direct superclass of the following four classes.
2. **MyCalculator** — this is the root component. It should register the application (on the class side), it should instantiate and render its subcomponents, and it should register any state for backtracking.

3. **MyKeypad** — this displays the keys that we use to interact with the calculator.

4. **MyDisplay** — this component displays the top of the stack and provides a button to call another component to display the detailed view.

5. **MyDisplayStack** — this component shows the detailed view of the stack and provides a button to answer back. It is a subclass of **MyDisplay**.

Create a package **MyCalculator**, and define **MyRPNWidget**.

Define the common style for the application.

Here is a minimal CSS for the application. You can make it more fancy if you like.

```css
MyRPNWidget >> style
    ^ 'table.keypad { float: left; }
td.key {
    border: 1px solid grey;
    background: lightgrey;
    padding: 4px;
    text-align: center;
}
table stack { float: left; }
td stackcell {
    border: 2px solid white;
    border-left-color: grey;
    border-right-color: grey;
    border-bottom-color: grey;
    padding: 4px;
    text-align: right;
}
td.small { font-size: 8pt; }
```

Define **MyCalculator** to be a root component and register itself as an application (i.e., implement **canBeRoot** and **initialize** on the class side).

Implement **MyCalculator>>renderContentOn:** to render something trivial (such as its name), and verify that the application runs in a browser.

**MyCalculator** is responsible for instantiating **MyStackMachine**, **MyKeypad** and **MyDisplay**.

Define **MyKeypad** and **MyDisplay** as subclasses of **MyRPNWidget**.

All three components will need access to a common instance of the stack machine, so define the instance variable **stackMachine** and an initialization method **setMyStackMachine:** in the common parent, **MyRPNWidget**. Add instance variables keypad and display to **MyCalculator** and initialize them in **MyCalculator>>initialize**. (Don't forget to send super **initialize**!)
<figure><img src="image_164.png" /><figcaption>**Figure 14.17:** Displaying the top of the stack.</figcaption></figure>

Pass the shared instance of the stack machine to the keypad and the display in the same initialize method.

Implement `MyCalculator>>renderContentOn:` to simply render in turn the keypad and the display. To correctly display the subcomponents, you must implement `MyCalculator>>children` to return an array with the keypad and the display. Implement placeholder rendering methods for the keypad and the display and verify that the calculator now displays its two subcomponents.

Now we will change the implementation of the display to show the top value of the stack.

Use a table with class keypad containing a row with a single table data cell with class `stackcell`.

Change the rendering method of the keypad to ensure that the number 0 is pushed on the stack in case it is empty. (Define and use `MyKeypad>>ensureStackMachineNotEmpty`.) Also make it display an empty table with class keypad. Now the calculator should display a single cell containing the value 0. If you toggle the halos, you should see something like this: Figure 14.17

Now let's implement an interface to interact with the stack.

First, define the following helper methods, which will make it easier to script the interface:

```javascript
MyKeypad >> renderStackButton: text callback: aBlock colSpan: anInteger
    on: html
    html tableData
        class: 'key';
        colSpan: anInteger;
    with:
        [ html anchor
            callback: aBlock;
            with: [ html html: text ]]

MyKeypad >> renderStackButton: text callback: aBlock on: html
    self
    renderStackButton: text
```
callback: aBlock
colSpan: 1
on: html

We will use these two methods to define the buttons on the keypad with
appropriate callbacks. Certain buttons may span multiple columns, but the
default is to occupy just one column.

Use the two helper methods to script the keypad as follows.

(Hint: start by getting the digit and Enter keys working, then the arithmetic
operators.)

MyKeypad >> renderContentOn: html
self ensureStackMachineNotEmpty.
html table
class: 'keypad';
with: [
html tableRow: [
self renderStackButton: '+' callback: [self stackOp: #add] on:
html.
self renderStackButton: '&ndash;' callback: [self stackOp:
#min] on: html.
self renderStackButton: '&times;' callback: [self stackOp:
#mul] on: html.
self renderStackButton: '&divide;' callback: [self stackOp:
#div] on: html.
self renderStackButton: '&plusmn;' callback: [self stackOp:
#neg] on: html ].
html tableRow: [
self renderStackButton: '1' callback: [self type: '1'] on:
html.
self renderStackButton: '2' callback: [self type: '2'] on:
html.
self renderStackButton: '3' callback: [self type: '3'] on:
html.
self renderStackButton: 'Drop' callback: [self
stackPopIfNotEmpty]
colSpan: 2 on: html ].
" and so on ...
html tableRow: [
self renderStackButton: '0' callback: [self type: '0']
colSpan: 2 on: html.
self renderStackButton: 'C' callback: [self stackClearTop] on:
html.
self renderStackButton: 'Enter'
callback: [self stackOp: #dup. self setClearMode]
colSpan: 2 on: html ]]

Check that the keypad displays properly. If you try to click on the keys, how-
ever, you will find that the calculator does not work yet.
Implement `MyKeypad>>type:` to update the top of the stack by appending the typed digit. You will need to convert the top value to a string, update it, and convert it back to an integer, something like this:

```kotlin
MyKeypad >> type: aString
stackMachine push: (self stackPopTopOrZero asString, aString)
asNumber.
```

The two methods `stackPopTopOrZero` and `stackPopIfNotEmpty` are used to guard against operating on an empty stack.

```kotlin
MyKeypad >> stackPopTopOrZero
^ stackMachine empty
ifTrue: [0]
ifFalse: [stackMachine pop]
```

```kotlin
MyKeypad >> stackPopIfNotEmpty
stackMachine empty
ifFalse: [stackMachine pop]
```

Now when you click on the digit keys the display should be updated. (Be sure that `MyStackMachine>>pop` returns the value popped, or this will not work!)

Next, we must implement `MyKeypad>>stackOp:.` Something like this will do the trick:

```kotlin
MyKeypad >> stackOp: op
[ stackMachine perform: op ] on: AssertionFailure do: [ ].
```

The point is that we are not sure that all operations will succeed. For example, addition will fail if we do not have two numbers on the stack. For the moment we can just ignore such errors. If we are feeling more ambitious later on, we can provide some user feedback in the error handler block.

The first version of the calculator should be working now. Try to enter some numbers by pressing the digit keys, hitting `Enter` to push a copy of the current value, and entering `+` to sum the top two values.

You will notice that typing digits does not behave the way you might expect. Actually the calculator should be aware of whether you are typing a new number, or appending to an existing number.

Adapt `MyKeypad>>type:` to behave differently depending on the current typing mode.

Introduce an instance variable `mode` which takes on one of the three values: the symbol `#typing` (when you are typing), `#push` (after you have performed a calculator operation and typing should force the top value to be pushed), or `#clear` (after you have performed `Enter` and the top value should be cleared before typing). The new `type:` method might look like this:

```kotlin
MyKeypad >> type: aString
self inPushMode ifTrue: [
```
```kotlin
stackMachine push: stackMachine top.
self stackClearTop ].
self inClearMode ifTrue: [ self stackClearTop ].
stackMachine push: (self stackPopTopOrZero asString, aString)
    asNumber.
```

Typing might work better now, but it is still frustrating not to be able to see
what is on the stack.

Define `MyDisplayStack` as a subclass of `MyDisplay`.

Add a button to the rendering method of `MyDisplay` which will call a new
instance of `MyDisplayStack`. You will need an HTML anchor that looks some-
thing like this:

```html
<html anchor
callback: [ self call: (MyDisplayStack new setMyStackMachine:
    stackMachine)];
with: 'open'
```

The callback will cause the current instance of `MyDisplay` to be temporarily
replaced by a new instance of `MyDisplayStack` whose job it is to display the
complete stack. When this component signals that it is done (i.e., by sending
self answer), then control will return to the original instance of `MyDisplay`.

Define the rendering method of `MyDisplayStack` to display all of the values on
the stack.

(You will either need to define an accessor for the stack machine's contents
or you can define `MyStackMachine>>do:` to iterate over the stack values.) The
stack display should also have a button labelled `close` whose callback will
simply perform `self answer`.

```html
<html anchor
callback: [ self answer];
with: 'close'
```

Now you should be able to *open* and *close* the stack while you are using the
calculator.

There is, however, one thing we have forgotten. Try to perform some op-
erations on the stack. Now use the *Back* button of your browser and try to
perform some more stack operations. For example, open the stack, type 1,
Enter twice and +. The stack should display 2 and 1. Now hit the *Back* button.
The stack now shows three times 1 again. Now if you type +, the stack shows 3.
Backtracking is not yet working.

Implement `MyCalculator>>states` to return an array with the contents of
the stack machine.

Check that backtracking now works correctly.
14.8 A quick look at AJAX

AJAX (Asynchronous JavaScript and XML) is a technique to make web appli-
cations more interactive by exploiting JavaScript functionality on the client
side.

Two well-known JavaScript libraries are Prototype (http://www.prototypejs.org) and script.aculo.us (http://script.aculo.us). Prototype provides a framework to ease writing JavaScript. script.aculo.us provides some additional features to support animations and drag-and-drop on top of Prototype. Both frameworks are supported in Seaside through the package Scriptaculous.

All ready made images have the Scriptaculous package extensions already
loaded. The latest version is available from http://www.squeaksource.com/
Seaside. An online demo is available at http://scriptaculous.seasidehosting.
st. Alternatively, if you have a enabled image running, simply go to http:
//localhost:8080/javascript/scriptaculous.

The Scriptaculous extensions follow the same approach as Seaside itself —
simply configure Pharo objects to model your application, and the needed
Javascript code will be generated for you.

Let us look at a simple example of how client-side Javascript support can
make our RPN calculator behave more naturally. Currently every keystroke to
enter a digit generates a request to refresh the page. We would like instead to
handle editing of the display on the client-side by updating the display in the
existing page.

To address the display from JavaScript code, we must first give it a unique id.

Update the calculator's rendering method as follows. (If you have not imple-
mented the tutorial example yourself, you can simply load the complete exam-
ple (PBE-SeasideRPN) from http://www.squeaksource.com/PharoByExample and
apply the suggested changes to the classes RPN* instead of My*.

MyCalculator >> renderContentOn: html
html div id: 'keypad'; with: keypad.
html div id: 'display'; with: display.

To be able to re-render the display when a keyboard button is pressed, the
keyboard needs to know the display component.

Add a display instance variable to MyKeypad, an initialize method MyKey-
pad>>setDisplay:, and call this from MyCalculator>>initialize. Now we
are able to assign some JavaScript code to the buttons by updating MyKey-
pad>>renderStackButton:callback:colSpan:on: as follows:

MyKeypad >> renderStackButton: text callback: aBlock colSpan: anInteger
on: html
html tableData
class: 'key';
colSpan: anInteger;
```javascript
with: [
    html anchor
        callback: aBlock;
        onClick: "handle Javascript event"
        (html scriptaculous updater
            id: 'display';
            callback: [ :r |
                        aBlock value.
                        r render: display ];
            return: false);
    with: [ html html: text ] ]
```

**Click:** `Click` specifies a JavaScript event handler. `html updater` returns an instance of `PT Updater`, a Smalltalk object representing the JavaScript `AJAX` Updater object (http://www.prototypejs.org/api/api更新器). This object performs `AJAX` requests and updates a container's contents based on the response text. `id:` tells the `updater` what HTML DOM element to update, in this case the contents of the `div` element with the `id` 'display'. `callback:` specifies a block that is triggered when the user presses the button. The block argument is a new `renderer r`, which we can use to render the display component. (Note: Even though HTML is still accessible, it is not valid anymore at the time this callback block is evaluated). Before rendering the display component we evaluate `aBlock` to perform the desired action.

**return:** `false` tells the JavaScript engine to not trigger the original link callback, which would cause a full refresh. We could instead remove the original anchor `callback:`, but like this the calculator will still work even if JavaScript is disabled.

Try the calculator again, and notice how a full page refresh is triggered every time you press a digit key. (The URL of the web page is updated at each keystroke.)

Although we have implemented the client-side behavior, we have not yet activated it. Now we will enable the Javascript event handling.

Click on the **Configure** link in the toolbar of the calculator.

Configure the `Libraries` attribute under the `General` section. (You may need to enable the modification of this attribute, by first selecting `Modify`). From the list of available libraries, select `PTDevelopmentLibrary` and apply the changes.

Instead of manually adding the library, you may also do it programmatically when you register the application:

```javascript
MyCalculator class >> initialize
    (WAAdmin register: self asApplicationAt: self applicationName)
    addLibrary: PTDevelopmentLibrary
```
<figure><img src="image_165.png" /></figure>

## Seaside: AJAX Processing (simplified)

Lukas Renggli, 2007

<caption>Figure 14.18: Seaside AJAX processing (simplified).</caption>

For this example the PTDevelopmentLibrary is sufficient, but for the full set of the scriptaculous extensions you need to add the SUDevelopmentLibrary, too.

Try the revised application. Note that the feedback is much more natural. In particular, a new URL is not generated with each keystroke.

You may well ask, yes, but how does this work? Figure 14.18 shows how the RPN applications would both without and with AJAX. Basically AJAX short-circuits the rendering to only update the display component. Javascript is responsible both for triggering the request and updating the corresponding DOM element. Have a look at the generated source-code, especially the JavaScript code:

```javascript
new Ajax. Updater(
  'display',
  'http://localhost/seaside/RPN+Calculator',
  {'evalScripts': true,
   'parameters': ['UNDERSCORES=zcdqfonqwbeYzkza',
                  'UNDERSCOREk=jMORHtqr', '9'].join('%')});
```
return false

For more advanced examples, have a further look at http://localhost:8080/javascript/scriptaculous.

## Hints

In case of server side problems use the Debugger. In case of client side problems use FireFox (http://www.mozilla.com) with the JavaScript debugger Fire-Bug (http://www.getfirebug.com/) plugin enabled.

## 14.9 Chapter summary

* The easiest way to get started is to download the *Seaside One-Click Experience* from http://seaside.st

* Turn the server on and off by evaluating `ZnZincServerAdaptor startOn: 8080` and `ZnZincServerAdaptor stop`.

* Toggle Halos to directly view application source code, run-time objects, CSS and HTML.

* Remove the root decoration class `WAToolDecoration` in the application configuration, to disable the toolbar.

* Send `WAAdmin applicationDefaults removeParent: WADevelopment-Configuration` instance, to disable toolbar for new Components

* Seaside web applications are composed of components, each of which is an instance of a subclass of `WAComponent`.

* Only a root component may be registered as an application. It should implement `canBeRoot` on the class side. Alternatively it may register itself as an application in its class-side `initialize` method by sending `WAAdmin register: self asApplicationAt: application path`. If you override description it is possible to return a descriptive application name that will be displayed in the configuration editor.

* To backtrack state, a component must implement the `states` method to answer an array of objects whose state will be restored if the user clicks the browser's *Back* button.

* A component renders itself by implementing `renderContentOn:`. The argument to this method is an HTML rendering `canvas` (usually called `html`).

* A component can render a subcomponent by sending `self render: subcomponent`.
* HTML is generated programmatically by sending messages to *brushes*. A brush is obtained by sending a message, such as *paragraph* or *div*, to the HTML canvas.

* If you send a cascade of messages to a brush that includes the message *with:*, then *with*: should be the last message sent. The *with*: message sets the contents *and* renders the result.

* Actions should appear only in callbacks. You should not change the state of the application while you are rendering it.

* You can bind various form widgets and anchors to instance variables with accessors by sending the message on: *instance variable of: object* to the brush.

* You can define the CSS for a component hierarchy by defining the method *style*, which should return a string containing the style sheet. (For deployed applications, it is more usual to refer to a style sheet located at a static URL.)

* Control flows can be programmed by sending *x call: y*, in which case component *x* will be replaced by *y* until *y* answers by sending *answer*: with a result in a callback. The receiver of *call*: is usually *self*, but may in general be any visible component.

* A control flow can also be specified as a *task* — a instance of a subclass of *WATask*. It should implement the method *go*, which should *call*: a series of components in a workflow.

* Use *WAComponents's* convenience methods *request:*, *inform:*, *confirm:* and *chooseFrom:caption*: for basic interactions.

* To prevent the user from using the browser's *Back* button to access a previous execution state of the web application, you can declare portions of the workflow to be a *transaction* by enclosing them in an *isolate: block*.
<figure><img src="image_166.png" /></figure>
CHAPTER 15

# Classes and metaclasses

As we saw in preceding chapters, in Pharo, everything is an object, and every
object is an instance of a class. Classes are no exception: classes are objects,
and class objects are instances of other classes. This object model captures
the essence of object-oriented programming, and is lean, simple, elegant
and uniform. However, the implications of this uniformity may confuse
newcomers.

Note that you do not need to fully understand the implications of this unifor-
mity to program fluently in Pharo. Nevertheless, the goal of this chapter is
twofold: (1) go as deep as possible and (2) show that there is nothing complex,
magic or special here: just simple rules applied uniformly. By following these
rules you can always understand why the situation is the way that it is.

15.1 Rules for classes and metaclasses

The Pharo object model is based on a limited number of concepts applied uniformly. To refresh your memory, here are the rules of the object model that we explored in Chapter : The Pharo Object Model.

**Rule 1** Everything is an object.

**Rule 2** Every object is an instance of a class.

**Rule 3** Every class has a superclass.

**Rule 4** Everything happens by sending messages.

**Rule 5** Method lookup follows the inheritance chain.

As we mentioned in the introduction to this chapter, a consequence of Rule 1 is that *classes are objects too*, so Rule 2 tells us that classes must also be in-
<figure><img src="image_167.png" /><figcaption>**Figure 15.1:** Sending the message `class` to a sorted collection</figcaption></figure>

stances of classes. The class of a class is called a *metaclass*. A metaclass is created automatically for you whenever you create a class. Most of the time you do not need to care or think about metaclasses. However, every time that you use the browser to browse the *class side* of a class, it is helpful to recall that you are actually browsing a different class. A class and its metaclass are two separate classes, even though the former is an instance of the latter.

To properly explain classes and metaclasses, we need to extend the rules from Chapter : The Pharo Object Model with the following additional rules.

**Rule 6** Every class is an instance of a metaclass.

**Rule 7** The metaclass hierarchy parallels the class hierarchy.

**Rule 8** Every metaclass inherits from *Class* and *Behavior*.

**Rule 9** Every metaclass is an instance of *Metaclass*.

**Rule 10** The metaclass of *Metaclass* is an instance of *Metaclass*.

Together, these 10 rules complete Pharo's object model.

We will first briefly revisit the 5 rules from Chapter : The Pharo Object Model with a small example. Then we will take a closer look at the new rules, using the same example.

## 15.2 Revisiting the Pharo object model

**Rule 1.** Since everything is an object, an ordered collection in Pharo is also an object.
15.3 Every class is an instance of a metaclass

OrderedCollection withAll: #(4 5 6 1 2 3)
>>> an OrderedCollection(4 5 6 1 2 3)

**Rule 2.** Every object is an instance of a class. The class of an ordered collection is the class OrderedCollection:

(OrderedCollection withAll: #(4 5 6 1 2 3)) class
>>> OrderedCollection

**Rule 3.** Every class has a superclass. The superclass of OrderedCollection is SequenceableCollection and the superclass of SequenceableCollection is Collection:

OrderedCollection superclass
>>> SequenceableCollection

SequenceableCollection superclass
>>> Collection

Collection superclass
>>> Object

Let us take an example. When we send the message asSortedCollection, we convert the ordered collection into a sorted collection. We verify simply as follows:

(OrderedCollection withAll: #(4 5 6 1 2 3)) asSortedCollection class
>>> SortedCollection

**Rule 4.** Everything happens by sending messagess, so we can deduce that withAll: is a message to OrderedCollection and asSortedCollection are messages sent to the ordered collection instance, and superclass is a message to OrderedCollection and SequenceableCollection, and Collection. The receiver in each case is an object, since everything is an object, but some of these objects are also classes.

**Rule 5.** Method lookup follows the inheritance chain, so when we send the message class to the result of (OrderedCollection withAll: #(4 5 6 1 2 3)) asSortedCollection, the message is handled when the corresponding method is found in the class Object, as shown in Figure 15.1.

## 15.3 Every class is an instance of a metaclass

As we mentioned earlier in Section 15.1, classes whose instances are themselves classes are called metaclasses.

### Metaclasses are implicit

Metaclasses are automatically created when you define a class. We say that they are *implicit* since as a programmer you never have to worry about them.
<figure><img src="image_168.png" /><figcaption>**Figure 15.2:** The metaclasses of `SortedCollection` and its superclasses (elided).</figcaption></figure>

An implicit metaclass is created for each class you create, so each metaclass has only a single instance.

Whereas ordinary classes are named, metaclasses are anonymous. However, we can always refer to them through the class that is their instance. The class of `SortedCollection`, for instance, is `SortedCollection` class, and the class of `Object` is `Object` class:

```
[SortedCollection class
>>> SortedCollection class]
[Object class
>>> Object class]
```

In fact metaclasses are not truly anonymous, their name is deduced from the one of their single instance

```
[SortedCollection class name
>>> 'SortedCollection class'
```

Figure 15.2 shows how each class is an instance of its metaclass. Note that we only skip `SequenceableCollection` and `Collection` from the figures and explanation due to space constraints. Their absence does not change the overall meaning.

## Querying Metaclasses

The fact that classes are also objects makes it easy for us to query them by sending messages. Let's have a look:

```
[OrderedCollection subclasses
>>> {SortedCollection . ObjectFinalizerCollection .
WeakOrderedCollection . OCLiteralList . GLMMultiValue}]
[SortedCollection subclasses
>>> #()
```
15.4 The metaclass hierarchy parallels the class hierarchy

<figure><img src="image_169.png" /><figcaption>Figure 15.3: The metaclass hierarchy parallels the class hierarchy (elided).</figcaption></figure>

```
[ SortedCollection allSuperclasses
>>> an OrderedCollection OrderedCollection SequenceableCollection
Collection Object ProtoObject)

[ SortedCollection instVarNames
>>> #('sortBlock')

[ SortedCollection allInstVarNames
>>> #('array' 'firstIndex' 'lastIndex' 'sortBlock')

[ SortedCollection selectors
>>> #(#indexForInserting: #sort:to: #all: #reSort #sortBlock:
#copyEmpty #addFirst: #insert:before: #defaultSort:to: #median
#at:put: #add: #= #collect: #flatCollect: #sort: #join: #sortBlock)
```

15.4 The metaclass hierarchy parallels the class hierarchy

Rule 7 says that the superclass of a metaclass cannot be an arbitrary class: it is constrained to be the metaclass of the superclass of the metaclass's unique instance.

```
[ SortedCollection class superclass
>>> OrderedCollection class

[ SortedCollection superclass class
>>> OrderedCollection class
```

This is what we mean by the metaclass hierarchy being parallel to the class hierarchy. Figure 15.3 shows how this works in the `SortedCollection` hierarchy.

```
[ SortedCollection class
>>> SortedCollection class

[ SortedCollection class superclass
>>> OrderedCollection class
```
<figure><img src="image_170.png" /><figcaption>**Figure 15.4:** Message lookup for classes is the same as for ordinary objects.</figcaption></figure>

SortedCollection class superclass superclass
>>> SequenceableCollection class

SortedCollection class superclass superclass superclass
>>> Object class

## Uniformity between Classes and Objects

It is interesting to step back a moment and realize that there is no difference between sending a message to an object and to a class. In both cases the search for the corresponding method starts in the *class of the receiver*, and *proceeds up the inheritance chain*.

Thus, messages sent to classes must follow the metaclass inheritance chain. Consider, for example, the method `withAll()`, which is implemented on the class side of `Collection`. When we send the message `withAll:` to the class `OrderedCollection`, then it is looked up the same way as any other message. The lookup starts in `OrderedCollection` class (since it starts in the class of the receiver and the receiver is `OrderedCollection`), and proceeds up the metaclass hierarchy until it is found in `Collection` class (see Figure 15.4). It returns a new instance of `OrderedCollection`.

OrderedCollection withAll: #(4 5 6 1 2 3)
>>> an OrderedCollection (4 5 6 1 2 3)

## Only one method lookup

Thus we see that there is one uniform kind of method lookup in Pharo. Classes are just objects, and behave like any other objects. Classes have the power to create new instances only because classes happen to respond to the message new, and because the method for new knows how to create new instances.
15.5 Every metaclass inherits from Class and Behavior

<figure><img src="image_171.png" /><figcaption>Figure 15.5: Classes are objects too.</figcaption></figure>

Normally, non-class objects do not understand this message, but if you have a good reason to do so, there is nothing stopping you from adding a new method to a non-metaclass.

Inspecting objects and classes

Since classes are objects, we can also inspect them.

Inspect OrderedCollection withAll: #(4 5 6 1 2 3) and OrderedCollection.

Notice that in one case you are inspecting an instance of OrderedCollection and in the other case the OrderedCollection class itself. This can be a bit confusing, because the title bar of the inspector names the *class* of the object being inspected.

The inspector on OrderedCollection allows you to see the superclass, instance variables, method dictionary, and so on, of the OrderedCollection class, as shown in Figure 15.5.

15.5 Every metaclass inherits from Class and Behavior

Every metaclass is a kind of a class (a class with a single instance), hence inherits from Class. Class in turn inherits from its superclasses, ClassDescription and Behavior. Since everything in Pharo is an object, these classes all inherit eventually from Object. We can see the complete picture in Figure 15.6.

Where is new defined?

To understand the importance of the fact that metaclasses inherit from Class and Behavior, it helps to ask where new is defined and how it is found. When
<figure><img src="image_172.png" /><figcaption>Figure 15.6: Metaclasses inherit from Class and Behavior.</figcaption></figure>

the message `new` is sent to a class, it is looked up in its metaclass chain and ultimately in its superclasses `Class`, `ClassDescription` and `Behavior` as shown in Figure 15.7.

The question *Where is new defined?* is crucial. `new` is first defined in the class `Behavior`, and it can be redefined in its subclasses, including any of the metaclass of the classes we define, when this is necessary. Now when a message `new` is sent to a class it is looked up, as usual, in the metaclass of this class, continuing up the superclass chain right up to the class `Behavior`, if it has not been redefined along the way.

Note that the result of sending `SortedCollection new` is an instance of `SortedCollection` and not of `Behavior`, even though the method is looked up in the class `Behavior! new` always returns an instance of `self`, the class that receives the message, even if it is implemented in another class.

```
SortedCollection new class
>>> SortedCollection "not Behavior!"
```

**Common mistake.** A common mistake is to look for `new` in the superclass of the receiving class. The same holds for `new:`, the standard message to create an object of a given size. For example, `Array new: 4` creates an array of 4 elements. You will not find this method defined in `Array` or any of its superclasses. Instead you should look in `Array class` and its superclasses, since that is where the lookup will start (See Figure 15.7).
<figure><img src="image_173.png" /><figcaption>**Figure 15.7:** new is an ordinary message looked up in the metaclass chain.</figcaption></figure>

Responsibilities of Behavior, ClassDescription, and Class

Behavior provides the minimum state necessary for objects that have instances, which includes a superclass link, a method dictionary and the class format. The class format is an integer that encodes the pointer/non-pointer distinction, compact/non-compact class distinction, and basic size of instances. Behavior inherits from Object, so it, and all of its subclasses, can behave like objects.

Behavior is also the basic interface to the compiler. It provides methods for creating a method dictionary, compiling methods, creating instances (i.e., new, basicNew, new:, and basicNew:), manipulating the class hierarchy (i.e., superclass:, addSubclass:), accessing methods (i.e., selectors, all Selectors, compiled MethodAt:), accessing instances and variables (i.e., allInstances, instVarNames...), accessing the class hierarchy (i.e., superclass, subclasses) and querying (i.e., hasMethods, includesSelector, canUnderstand:, inheritsFrom:, isVariable).

ClassDescription is an abstract class that provides facilities needed by its two direct subclasses, Class and Metaclass. ClassDescription adds a number of facilities to the base provided by Behavior: named instance variables, the categorization of methods into protocols, the maintenance of change sets and the logging of changes, and most of the mechanisms needed for filing out changes.

Class represents the common behaviour of all classes. It provides a class name, compilation methods, method storage, and instance variables. It pro-
<figure><img src="image_174.png" /><figcaption>Figure 15.8: Every metaclass is a Metaclass.</figcaption></figure>

vides a concrete representation for class variable names and shared pool variables (`addClassVarName:`, `addSharedPool:`, `initialize`). Since a metaclass is a class for its sole instance (i.e., the non-meta class), all metaclasses ultimately inherit from `Class` (as shown by Figure 15.9).

## 15.6 Every metaclass is an instance of Metaclass

One question left is since metaclasses are objects too, they should be instances of another class, but which one? Metaclasses are objects too; they are instances of the class `Metaclass` as shown in Figure 15.8. The instances of class `Metaclass` are the anonymous metaclasses, each of which has exactly one instance, which is a class.

`Metaclass` represents common metaclass behaviour. It provides methods for instance creation (`subclassOf:`), creating initialized instances of the metaclass's sole instance, initialization of class variables, metaclass instance, method compilation, and class information (inheritance links, instance variables, etc.).

## 15.7 The metaclass of Metaclass is an instance of `Meta-class`

The final question to be answered is: what is the class of `Metaclass` `class`?
The answer is simple: it is a metaclass, so it must be an instance of `Metaclass`, just like all the other metaclasses in the system (see Figure 15.9).
15.7 The metaclass of `Metaclass` is an instance of `Metaclass`

<figure><img src="image_175.png" /><figcaption>**Figure 15.9:** All metaclasses are instances of the class `Metaclass`, even the metaclass of `Metaclass`.</figcaption></figure>

Figure 15.9 shows how all metaclasses are instances of `Metaclass`, including the metaclass of `Metaclass` itself. If you compare Figures 15.8 and 15.9 you will see how the metaclass hierarchy perfectly mirrors the class hierarchy, all the way up to `Object` class.

The following examples show us how we can query the class hierarchy to demonstrate that Figure 15.9 is correct. (Actually, you will see that we told a white lie — `Object` class superclass `--> ProtoObject` class, not `Class`. In Pharo, we must go one superclass higher to reach `Class`.)

```
[ Collection superclass
>>> Object
[ Collection class superclass
>>> Object class
Object class superclass superclass
>>> Class "NB: skip ProtoObject class"
Class superclass
>>> ClassDescription
ClassDescription superclass
>>> Behavior
Behavior superclass
>>> Object
[ Collection class class
>>> Metaclass
```
Object class class

>>> Metaclass

Behavior class class

>>> Metaclass

Metaclass class class

>>> Metaclass

Metaclass superclass

>>> ClassDescription

15.8 Chapter summary

This chapter gave an in-depth look into the uniform object model, and a more
thorough explanation of how classes are organized. If you get lost or confused,
you should always remember that message passing is the key: you look for the
method in the class of the receiver. This works on *any* receiver. If the method
is not found in the class of the receiver, it is looked up in its superclasses.

* Every class is an instance of a metaclass. Metaclasses are implicit. A metaclass is created automatically when you create the class that is its sole instance. A metaclass is simply a class whose unique instance is a class.

* The metaclass hierarchy parallels the class hierarchy. Method lookup for classes parallels method lookup for ordinary objects, and follows the metaclass's superclass chain.

* Every metaclass inherits from *Class* and *Behavior*. Every class is a *Class*. Since metaclasses are classes too, they must also inherit from *Class*. *Behavior* provides behaviour common to all entities that have instances.

* Every metaclass is an instance of *Metaclass*. *ClassDescription* provides everything that is common to *Class* and *Metaclass*.

* The metaclass of *Metaclass* is an instance of *Metaclass*. The *instance-of* relation forms a closed loop, so *Metaclass class class* is *Metaclass*.
CHAPTER 16

Reflection

Pharo is a reflective programming language. In a nutshell, this means that programs are able to *reflect* on their own execution and structure. More technically, this means that the *metaobjects* of the runtime system can be *reified* as ordinary objects, which can be queried and inspected. The metaobjects in Pharo are classes, metaclasses, method dictionaries, compiled methods, but also the run-time stack, processes, and so on. This form of reflection is also called * introspection*, and is supported by many modern programming languages.

Conversely, it is possible in Pharo to modify reified metaobjects and reflect these changes back to the runtime system (see Figure 16.1). This is also called

<figure><img src="image_176.png" /><figcaption>**Figure 16.1:** Reification and reflection.</figcaption></figure>
intercession, and is supported mainly by dynamic programming languages, and only to a very limited degree by static languages. So pay attention when people say that Java is a reflective language, it is an introspective one not a reflective one.

A program that manipulates other programs (or even itself) is a *metaprogram*. For a programming language to be reflective, it should support both introspection and intercession. Introspection is the ability to *examine* the data structures that define the language, such as objects, classes, methods and the execution stack. Intercession is the ability to *modify* these structures, in other words to change the language semantics and the behavior of a program from within the program itself. *Structural reflection* is about examining and modifying the structures of the run-time system, and *behavioural reflection* is about modifying the interpretation of these structures.

In this chapter we will focus mainly on structural reflection. We will explore many practical examples illustrating how Pharo supports introspection and metaprogramming.

## 16.1 Introspection

Using the inspector, you can look at an object, change the values of its instance variables, and even send messages to it.

Evaluate the following code in a playground:

```pharo
w := GTPlayground openLabel: 'My Playground'.
w inspect
```

This will open a second playground and an inspector. The inspector shows the internal state of this new playground, listing its instance variables on the left (borderColor, borderWidth, bounds...) and the value of the selected instance variable on the right. The bounds instance variable represents the precise area occupied by the playground.

Now choose the inspector and click the playground area of the inspector which has a comment on top and type `self bounds: (Rectangle origin: 10@10 corner: 300@300)` in it or select *asshown* in Figure 16.2 and then *Do It* like you do with a code of a Playground.

Immediately you will see the Playground we created change and resize itself.

### Accessing instance variables

How does the inspector work? In Pharo, all instance variables are protected. In theory, it is impossible to access them from another object if the class doesn't define any accessor. In practice, the inspector can access instance variables without needing accessors, because it uses the reflective abilities of Pharo. Classes define instance variables either by name or by numeric
<figure><img src="image_177.png" /><figcaption>**Figure 16.2:** Inspecting a Workspace.</figcaption></figure>

indices. The inspector uses methods defined by the `Object` class to access them: `instVarAt`: index and `instVarNamed`: aString can be used to get the value of the instance variable at position index or identified by aString, respectively. Similarly, to assign new values to these instance variables, it uses `instVarAt`: put: and `instVarNamed`: put:.

For instance, you can change the value of the `w` binding of the first workspace by evaluating:

```
[w instVarNamed:'bounds' put: (Rectangle origin: 10@10 corner: 500@500).
```

**Important** Caveat: Although these methods are useful for building development tools, using them to develop conventional applications is a bad idea: these reflective methods break the encapsulation boundary of your objects and can therefore make your code much harder to understand and maintain.

Both `instVarAt:` and `instVarAt:put:` are primitive methods, meaning that they are implemented as primitive operations of the Pharo virtual machine. If you consult the code of these methods, you will see the special pragma syntax `<primitive: N>` where N is an integer.

```
Object >> instVarAt: index
    "Primitive. Answer a fixed variable in an object. ..."

<primitive: 173 error: ec>
self primitiveFailed
```
<figure><img src="image_178.png" /><figcaption>**Figure 16.3:** Displaying all instance variables of a GTPlayground.</figcaption></figure>

Any Pharo code after the primitive declaration is executed only if the primitive fails. This also allows the debugger to be started on primitive methods. In this specific case, there is no way to implement this method, so the whole method just fails.

Other methods are implemented on the VM for faster execution. For example some arithmetic operations on SmallInteger :

* aNumber
  "Primitive. Multiply the receiver by the argument and answer with the
   result if it is a SmallInteger. Fail if the argument or the result
   is not a
   SmallInteger. Essential. No Lookup. See Object documentation
   whatIsAPrimitive."

<primitive: 9>
^ super * aNumber

If this primitive fails, for example if the VM does not handle the type of the argument, the Pharo code is executed. Although it is possible to modify the code of primitive methods, beware that this can be risky business for the stability of your Pharo system.

Figure 16.3 shows how to display the values of the instance variables of an arbitrary instance (w) of class GTPlayground. The method allInstVarNames returns all the names of the instance variables of a given class.
## 16.1 Introspection

```groovy
GTPlayground allInstVarNames
>>> 
#(#registry #suspendAll #suspendedAnnouncemets #logger #pane #title
#titleIcon #transformation #actions #condition #implicitNotNil
#dynamicActionsBlock #color #customValidation #shouldValidate
#acceptsSelection #parentPrototype #registeredAnnouncers
#updateActions #selectionActions #selectionDynamicActionsBlock
#implicitAllNil #rawSelectionTransmissions #statusPane #sourceLink
#initializationBlock #cachedDisplayedValue #labelActionBlock
#portChangeActions #wantsSteps #stepTime #stepCondition
#presentations #arrangement)

w := GTPlayground someInstance.
w class allInstVarNames collect: [:each | each -> (w instVarNamed:
    each)]
```

In the same spirit, it is possible to gather instances that have specific properties iterating over instances of a class using an iterator such as `select:`. For instance, to get all objects who are directly included in the world morph (the main root of the graphical displayed elements), try this expression:

```groovy
Morph allSubInstances
select: [ :each |
        | own |
        own := (each instVarNamed: 'owner').
        own isNil and: [ own isWorldMorph ]]
```

## Querying classes and interfaces

The development tools in Pharo (system browser, debugger, inspector...) all use the reflective features we have seen so far.

Here are a few other messages that might be useful to build development tools:

`isKindOf:` aClass returns true if the receiver is instance of aClass or of one of its superclasses. For instance:

```groovy
1.5 class
>>> BoxedFloat64
1.5 isKindOf: Float
>>> true
1.5 isKindOf: Number
>>> true
1.5 isKindOf: Integer
>>> false
```

`respondsTo:` aSymbol returns true if the receiver has a method whose selector is aSymbol. For instance:
```java
    1.5 respondsTo: #floor
>>> true "since Number implements floor"

    1.5 floor
>>> 1

Exception respondsTo: #,
>>> true "exception classes can be grouped"
```

**Important Caveat:** Although these features are especially useful for implementing development tools, they are normally not appropriate for typical applications. Asking an object for its class, or querying it to discover which messages it understands, are typical signs of design problems, since they violate the principle of encapsulation. Development tools, however, are not normal applications, since their domain is that of software itself. As such these tools have a right to dig deep into the internal details of code.

## Code metrics

Let's see how we can use Pharo's introspection features to quickly extract some code metrics. Code metrics measure such aspects as the depth of the inheritance hierarchy, the number of direct or indirect subclasses, the number of methods or of instance variables in each class, or the number of locally defined methods or instance variables. Here are a few metrics for the class Morph, which is the superclass of all graphical objects in Pharo, revealing that it is a huge class, and that it is at the root of a huge hierarchy. Maybe it needs some refactoring!

```ruby
"inheritance depth"
Morph allSuperclasses size.
>>> 2

"number of methods"
Morph all selectors size.
>>> 1304

"number of instance variables"
Morph allInstVarNames size.
>>> 6

"number of new methods"
Morph selectors size.
>>> 896

"number of new variables"
Morph instVarNames size.
>>> 6

"direct subclasses"
Morph subclasses size.
>>> 63
```
16.2 Browsing code

```json
  "total subclasses"
  Morph allSubclasses size.
>>> 376

  "total lines of code!"
  Morph linesOfCode.
>>> 4964
```

One of the most interesting metrics in the domain of object-oriented languages is the number of methods that extend methods inherited from the superclass. This informs us about the relation between the class and its super-classes. In the next sections we will see how to exploit our knowledge of the runtime structure to answer such questions.

## 16.2 Browsing code

In Pharo, everything is an object. In particular, classes are objects that provide useful features for navigating through their instances. Most of the messages we will look at now are implemented in `Behavior`, so they are understood by all classes.

For example, you can obtain a random instance of a given class by sending it the message `someInstance`.

```json
Point someInstance
>>> 0@0
```

You can also gather all the instances with `allInstances`, or the number of active instances in memory with `instanceCount`.

```json
ByteString allInstances
>>> #('collection' 'position' ...)

ByteString instanceCount
>>> 104565

String allSubInstances size
>>> 101675
```

These features can be very useful when debugging an application, because you can ask a class to enumerate those of its methods exhibiting specific properties. Here are some more interesting and useful methods for code discovery through reflection.

**whichSelectorsAccess**: returns the list of all selectors of methods that read or write the instance variable named by the argument

**whichSelectorsStoreInto**: returns the selectors of methods that modify the value of an instance variable

**whichSelectorsReferTo**: returns the selectors of methods that send a given message
```
[ Point which Selectors Access: 'x'
>>> #(#degrees #grid: #roundTo: #nearestPointAlongLineFrom: to: ...)
```

```
[ Point which Selectors Store Into: 'x'
>>> #(#bitShiftPoint: #setR: degrees: #setX: setY: #fromSton:)
```

```
[ Point which Selectors Refer To: #+
>>> an OrderedCollection(#degrees #reflectedAbout: #grid: ...)
```

The following messages take inheritance into account:

**whichClassIncludesSelector:** returns the superclass that implements the given message

**unreferencedInstanceVariables** returns the list of instance variables that are neither used in the receiver class nor any of its subclasses

```
[ Rectangle whichClassIncludesSelector: #inspect
>>> Object
```

```
[ Rectangle unreferencedInstanceVariables
>>> #()
```

**SystemNavigation** is a facade that supports various useful methods for querying and browsing the source code of the system. **SystemNavigation default** returns an instance you can use to navigate the system. For example:

```
[ SystemNavigation default allClassesImplementing: #yourself
>>> {Object}
```

The following messages should also be self-explanatory:

```
[ SystemNavigation default allSentMessages size
>>> 370
```

```
[ (SystemNavigation default allUnsentMessagesIn: Object selectors) size
>>> 31
```

```
[ SystemNavigation default allUnimplementedCalls size
>>> 521
```

Note that messages implemented but not sent are not necessarily useless, since they may be sent implicitly (e.g., using `perform:`). Messages sent but not implemented, however, are more problematic, because the methods sending these messages will fail at runtime. They may be a sign of unfinished implementation, obsolete APIs, or missing libraries.

**Point allCallsOn** returns all messages sent explicitly to Point as a receiver.

All these features are integrated into the programming environment of Pharo, in particular the code browsers. As we mentioned before, there are convenient keyboard shortcuts for browsing all implementors (`CMD-b CMD-m`) and browsing senders (`CMD-b CMD-n`) of a given message. What is perhaps not so well known is that there are many such pre-packaged queries implemented
16.3 Classes, method dictionaries and methods

<figure><img src="image_179.png" /><figcaption>Figure 16.4: Browse all implementations of ifTrue:.</figcaption></figure>

as methods of the SystemNavigation class in the browsing protocol. For example, you can programmatically browse all implementors of the message ifTrue: by evaluating:

```
[ SystemNavigation default browseAllImplementorsOf: #ifTrue:
```

Particularly useful are the methods browseAllSelect: and browseMethodsWithSourceString:matchCase:.. Here are two different ways to browse all methods in the system that perform super sends (the first way is rather brute force, the second way is better and eliminates some false positives):

```
[ SystemNavigation default browseMethodsWithSourceString: 'super'
    matchCase: true.
SystemNavigation default browseAllSelect: [:method | method
    sendsToSuper ].
```

16.3 Classes, method dictionaries and methods

Since classes are objects, we can inspect or explore them just like any other object.

Evaluate Point inspect.

In Figure 16.5, the inspector shows the structure of class Point. You can see that the class stores its methods in a dictionary, indexing them by their selector. The selector \*\* points to the decompiled bytecode of Point\*\*.

Let us consider the relationship between classes and methods. In Figure 16.6 we see that classes and metaclasses have the common superclass Behavior. This is where new is defined, amongst other key methods for classes. Every class has a method dictionary, which maps method selectors to compiled
<figure><img src="image_180.png" /><figcaption>Figure 16.5: Inspector on class Point and the bytecode of its \*\* method.</figcaption></figure>

<figure><img src="image_181.png" /><figcaption>Figure 16.6: Classes, method dictionaries and compiled methods</figcaption></figure>

methods. Each compiled method knows the class in which it is installed. In Figure 16.5 we can even see that this is stored in an association in `literal6`.

We can exploit the relationships between classes and methods to pose queries about the system. For example, to discover which methods are newly introduced in a given class, i.e., do not override superclass methods, we can navigate from the class to the method dictionary as follows:

```json
[:
aClass| aClass methodDict keys select: [:
aMethod |
  (aClass superclass canUnderstand: aMethod) not ]] value: SmallInteger
>>> an IdentitySet(#threeDigitName #printStringBase:nDigits: ...)
```
A compiled method does not simply store the bytecode of a method. It is also an object that provides numerous useful methods for querying the system. One such method is `isAbstract` (which tells if the method sends subclass-Responsibility). We can use it to identify all the abstract methods of an abstract class.

```sql
[ :aClass | aClass methodDict keys select: [ :aMethod |
    (aClass>>aMethod) isAbstract ] ] value: Number
>>> an IdentitySet(#storeOn:base: #printOn:base: #+ #- #* #/ ...)
```

Note that this code sends the `>>` message to a class to obtain the compiled method for a given selector.

To browse the super-sends within a given hierarchy, for example within the `Collections` hierarchy, we can pose a more sophisticated query:

```sql
class := Collection.
SystemNavigation default
    browseMessageList: (class withAllSubclasses gather: [:each |
        each methodDict associations
            select: [:assoc | assoc value sendsToSuper]
            thenCollect: [:assoc | RGMethodDefinition realClass: each
                selector: assoc key]])
    name: 'Supersedes of ', class name, ' and its subclasses'
```

Note how we navigate from classes to method dictionaries to compiled methods to identify the methods we are interested in. A `RGMethodDefinition` is a lightweight proxy for a compiled method that is used by many tools. There is a convenience method `CompiledMethod>>methodReference` to return the method reference for a compiled method.

```sql
(Object>>#=) methodReference selector
>>> #=
```

## 16.4 Browsing environments

Although `SystemNavigation` offers some useful ways to programmatically query and browse system code, there are more ways. The `Browser`, which is integrated into Pharo, allows us to restrict the environment in which a search is to perform.

Suppose we are interested to discover which classes refer to the class `Point` but only in its own package.

Open a browser on the class `Point`.

Action-click on the top level package `Kernel` in the package pane and select `Browse scoped`. A new browser opens, showing only the package `Kernel` and all classes within this package (and some classes which have extension methods from this package). Now, in this browser, select again the class `Point`,
Action-click on the class name and select Analyse > Class refs. This will show all methods that have references to the class Point but only those from the package Kernel. Compare this result with the search from a Browser without restricted scope.

This scope is what we call a *Browsing Environment* (class RBBrowserEnvironment). All other searches, like *senders of a method* or *implementors of a method* from within this browser are restricted to this environment too.

Browser environments can also be created programmatically. Here, for example, we create a new RBB browserEnvironment for Collection and its subclasses, select the super-sending methods, and browse the resulting environment.

((RBB browserEnvironment new forClasses: (Collection withAllSubclasses))
  selectMethods: [:method | method sendsToSuper])
  browse.

Note how this is considerably more compact than the earlier, equivalent example using SystemNavigation.

Finally, we can find just those methods that send a different super message programmatically as follows:

((RBB browserEnvironment new forClasses: (Collection withAllSubclasses))
  selectMethods: [:method |
    method sendsToSuper
  and: [(method parseTree superMessages includes: method selector)
        not]])
  browse

Here we ask each compiled method for its (Refactoring Browser) parse tree, in order to find out whether the super messages differ from the method's selector. Have a look at the querying protocol of the class RBProgramNode to see some of the things we can ask of parse trees.

Instead of browsing the environment in a System Browser, we can spawn a MessageBrowser from the list of all methods in this environment.

MessageBrowser browse: ((RBB browserEnvironment new forClasses:
  (Collection withAllSubclasses))
  selectMethods: [:method |
    method sendsToSuper
  and: [(method parseTree superMessages includes: method selector)
        not]]) methods
  title: 'Collection methods sending different super'

In Figure 16.7 we can see that 5 such methods have been found within the Collection hierarchy, including `Collection>>printNameOn:`, which sends `super printOn:.`
16.5 Accessing the run-time context

<figure><img src="image_182.png" /><figcaption>Figure 16.7: Finding methods</figcaption></figure>

16.5 Accessing the run-time context

We have seen how Pharo's reflective capabilities let us query and explore objects, classes and methods. But what about the run-time environment?

Method contexts

In fact, the run-time context of an executing method is in the virtual machine — it is not in the image at all! On the other hand, the debugger obviously has access to this information, and we can happily explore the run-time context, just like any other object. How is this possible?

Actually, there is nothing magical about the debugger. The secret is the pseudo-variable `thisContext`, which we have encountered only in passing before. Whenever `thisContext` is referred to in a running method, the entire run-time context of that method is reified and made available to the image as a series of chained `Context` objects.

We can easily experiment with this mechanism ourselves.

Change the definition of `Integer>>factorial` by inserting the expression `thisContext inspect. self halt.` as shown below:

```
Integer>>factorial
    "Answer the factorial of the receiver."
    self = 0 ifTrue: [thisContext inspect. self halt. ^ 1].
    self > 0 ifTrue: [^ self * (self - 1) factorial].
    self error: 'Not valid for negative integers'
```
<figure><img src="image_183.png" /><figcaption>**Figure 16.8:** Inspecting *thisContext*.</figcaption></figure>

Now evaluate `3 factorial` in a workspace. You should obtain both a debugger window and an inspector, as shown in Figure 16.8.

Inspecting *thisContext* gives you full access to the current execution context, the stack, the local tempories and arguments, the senders chain and the receiver. Welcome to the poor man's debugger! If you now browse the class of the explored object (i.e., by evaluating *self* browse in the bottom pane of the inspector) you will discover that it is an instance of the class *Context*, as is each sender in the chain.

*thisContext* is not intended to be used for day-to-day programming, but it is essential for implementing tools like debuggers, and for accessing information about the call stack. You can evaluate the following expression to discover which methods make use of *thisContext*:

```
SystemNavigation default browseMethodsWithSourceString: 'thisContext'
    matchCase: true
```

As it turns out, one of the most common applications is to discover the sender of a message. Here is a typical application:

```
subclassResponsibility
    "This message sets up a framework for the behavior of the class"
```
16.5 Accessing the run-time context

subclasses.
Announce that the subclass should have implemented this message.
SubclassResponsibility signalFor: thisContext sender selector

By convention, methods that send `self subclassResponsibility` are consid-
ered to be abstract. But how does `Object>>subclassResponsibility` provide
a useful error message indicating which abstract method has been invoked?
Very simply, by asking `thisContext` for the sender.

Intelligent breakpoints

The Pharo way to set a breakpoint is to evaluate `self halt` at an interesting
point in a method. This will cause `thisContext` to be reified, and a debugger
window will open at the breakpoint. Unfortunately this poses problems for
methods that are intensively used in the system.

Suppose, for instance, that we want to explore the execution of `Morph>>openInWorld`. Setting a breakpoint in this method is problematic.

Pay attention the following experiment will break everything! Take a fresh
image and set the following breakpoint:

Morph >> openInWorld
"Add this morph to the world."
self halt.
self openInWorld: self currentWorld

Notice how your image immediately freezes as soon as you try to open any
new Morph (Menu/Window/...)! We do not even get a debugger window. The
problem is clear once we understand that 1) Morph>>openInWorld is used by
many parts of the system, so the breakpoint is triggered very soon after we
interact with the user interface, but 2) the debugger itself sends openInWorld as
soon as it opens a window, preventing the debugger from opening! What we
need is a way to conditionally halt only if we are in a context of interest. This is
exactly what Object>>haltIf: offers.

Suppose now that we only want to halt if `openInWorld` is sent from, say, the
context of `MorphTest>>testOpenInWorld`.

Fire up a fresh image again, and set the following breakpoint:

Morph>>openInWorld
"Add this morph to the world."
self haltIf: #testOpenInWorld.
self openInWorld: self currentWorld

This time the image does not freeze. Try running the MorphTest.

MorphTest run:#testOpenInWorld.
How does this work? Let's have a look at `Object>>haltIf:`. It first calls `if:` with the condition to the `Exception` class `Halt`. This method itself will check if the condition is a symbol, which is true in this case and finally calls

```javascript
Object >> haltIfCallChainContains: aSelector

| cntxt |
cntxt := thisContext.
    [cntxt sender isNil] whileFalse: [
        cntxt := cntxt sender.
        (cntxt selector = aSelector) ifTrue: [self signal]].
```

Starting from `thisContext`, `haltIfCallChainContains:` goes up through the execution stack, checking if the name of the calling method is the same as the one passed as parameter. If this is the case, then it signals itself, the exception which, by default, summons the debugger.

It is also possible to supply a boolean or a boolean block as an argument to `haltIf:`, but these cases are straightforward and do not make use of `thisContext`.

## 16.6 Intercepting messages not understood

So far we have used Pharo's reflective features mainly to query and explore objects, classes, methods and the run-time stack. Now we will look at how to use our knowledge of its system structure to intercept messages and modify behaviour at run time.

When an object receives a message, it first looks in the method dictionary of its class for a corresponding method to respond to the message. If no such method exists, it will continue looking up the class hierarchy, until it reaches `Object`. If still no method is found for that message, the object will *send itself* the message `doesNotUnderstand:` with the message selector as its argument. The process then starts all over again, until `Object>>doesNotUnderstand:` is found, and the debugger is launched.

But what if `doesNotUnderstand:` is overridden by one of the subclasses of `Object` in the lookup path? As it turns out, this is a convenient way of realizing certain kinds of very dynamic behaviour. An object that does not understand a message can, by overriding `doesNotUnderstand:`, fall back to an alternative strategy for responding to that message.

Two very common applications of this technique are 1) to implement lightweight proxies for objects, and 2) to dynamically compile or load missing code.

### Lightweight proxies

In the first case, we introduce a *minimal object* to act as a proxy for an existing object. Since the proxy will implement virtually no methods of its own, any
message sent to it will be trapped by `doesNotUnderstand:`. By implementing
this message, the proxy can then take special action before delegating the
message to the real subject it is the proxy for.

Let us have a look at how this may be implemented.

We define a LoggingProxy as follows:

```kotlin
ProtoObject subclass: #LoggingProxy
    instanceVariableNames: 'subject invocationCount'
    classVariableNames: ''
    package: 'PBE-Reflection'
```

Note that we subclass ProtoObject rather than Object because we do not
want our proxy to inherit around 400 methods (!) from Object.

```kotlin
Object methodDict size
>>> 397
```

Our proxy has two instance variables: the subject it is a proxy for, and a
count of the number of messages it has intercepted. We initialize the two
instance variables and we provide an accessor for the message count. Initially
the subject variable points to the proxy object itself.

```kotlin
LoggingProxy >> initialize
    invocationCount := 0.
    subject := self.
```

```kotlin
LoggingProxy >> invocationCount
    ^ invocationCount
```

We simply intercept all messages not understood, print them to the Tran-
script, update the message count, and forward the message to the real sub-
ject.

```kotlin
LoggingProxy >> doesNotUnderstand: aMessage
    Transcript show: 'performing ', aMessage printString; cr.
    invocationCount := invocationCount + 1.
    ^ aMessage sendTo: subject
```

Here comes a bit of magic. We create a new Point object and a new Logging-
Proxy object, and then we tell the proxy to become: the point object:

```kotlin
point := 1@2.
LoggingProxy new become: point.
```

This has the effect of swapping all references in the image to the point to now
refer to the proxy, and vice versa. Most importantly, the proxy's subject
instance variable will now refer to the point!

```kotlin
point invocationCount
>>> 0
point + (3@4)
>>> 4@6
```
point invocationCount

>>> 1

This works nicely in most cases, but there are some shortcomings:

point class

>>> LoggingProxy

Actually the method class is implemented in ProtoObject, but even if it
were implemented in Object, which LoggingProxy does not inherit from, it
isn't actually send to the LoggingProxy or its subject. The message is directly
answered by the virtual machine. yourself is also never truly sent.

Other messages that may be directly interpreted by the VM, depending on the
receiver, include:

+ - < > <= >= = ~ = * / \ == @ bitShift: // bitAnd: bitOr: at: at:put:
size next nextPut: atEnd blockCopy: value value: do: new new: x y.

Selectors that are never sent, because they are inlined by the compiler and
 transformed to comparison and jump bytecodes:

ifTrue: ifFalse: ifTrue: ifFalse: ifFalse: ifTrue: and: or: while-
False: whileTrue: whileFalse whileTrue to: do: to: by: do: caseOf:
caseOf: otherwise: ifNil: ifNotNil: ifNil: ifNotNil: ifNotNil: ifNil:

Attempts to send these messages to non-boolean normally results in an excep-
tion from the VM as it can not use the inlined dispatching for non-boolean
receivers. You can intercept this and define the proper behavior by overrid-
ing mustBeBoolean in the receiver or by catching the NonBooleanReceiver
exception.

Even if we can ignore such special message sends, there is another fundamen-
tal problem which cannot be overcome by this approach: self-sends cannot
be intercepted:

point := 1@2.
LoggingProxy new become: point.

point invocationCount

>>> 0

point rectangle: (3@4)

>>> 1@2 corner: 3@4

point invocationCount

>>> 1

Our proxy has been cheated out of two self-sends in the rect: method:

Point >> rect: aPoint

^ Rectangle origin: (self min: aPoint) corner: (self max: aPoint)

Although messages can be intercepted by proxies using this technique, one
should be aware of the inherent limitations of using a proxy. In Section 16.7
we will see another, more general approach for intercepting messages.
## Generating missing methods

The other most common application of intercepting not understood messages is to dynamically load or generate the missing methods. Consider a very large library of classes with many methods. Instead of loading the entire library, we could load a stub for each class in the library. The stubs know where to find the source code of all their methods. The stubs simply trap all messages not understood, and dynamically load the missing methods on demand. At some point, this behaviour can be deactivated, and the loaded code can be saved as the minimal necessary subset for the client application.

Let us look at a simple variant of this technique where we have a class that automatically adds accessors for its instance variables on demand:

```
DynamicAccessors >> doesNotUnderstand: aMessage
| messageName |
messageName := aMessage selector asString.
(self class instVarNames includes: messageName)
ifTrue: [
    self class compile: messageName, String cr, ' ^ ', messageName.
    ^ aMessage sendTo: self ].
^ super doesNotUnderstand: aMessage
```

Any message not understood is trapped here. If an instance variable with the same name as the message sent exists, then we ask our class to compile an accessor for that instance variables and we re-send the message.

Suppose the class `DynamicAccessors` has an (uninitialized) instance variable `x` but no pre-defined accessor. Then the following will generate the accessor dynamically and retrieve the value:

```
myDA := DynamicAccessors new.
myDA x
>>> nil
```

Let us step through what happens the first time the message `x` is sent to our object (see Figure 16.9).

(1) We send `x` to `myDA`, (2) the message is looked up in the class, and (3) not found in the class hierarchy. (4) This causes `self doesNotUnderstand: #x` to be sent back to the object, (5) triggering a new lookup. This time `doesNotUnderstand:` is found immediately in `DynamicAccessors`, (6) which asks its class to compile the string `'x ^ x'`. The `compile` method is looked up (7), and (8) finally found in `Behavior`, which (9-10) adds the new compiled method to the method dictionary of `DynamicAccessors`. Finally, (11-13) the message is resent, and this time it is found.

The same technique can be used to generate setters for instance variables, or other kinds of boilerplate code, such as visiting methods for a `Visitor`.

Note the use of `Object>>perform:` in step (12) which can be used to send messages that are composed at run-time:
<figure><img src="image_184.png" /><figcaption>Figure 16.9: Dynamically creating accessors.</figcaption></figure>

```
5 perform: #factorial
>>> 120

6 perform: ('fac', 'torial') asSymbol
>>> 720

4 perform: #max: withArguments: (Array with: 6)
>>> 6
```

## 16.7 Objects as method wrappers

We have already seen that compiled methods are ordinary objects in Pharo, and they support a number of methods that allow the programmer to query the runtime system. What is perhaps a bit more surprising, is that *any object* can play the role of a compiled method. All it has to do is respond to the method `run:with:in:` and a few other important messages.

Define an empty class Demo. Evaluate `Demo new answer42` and notice how the usual `Message Not Understood` error is raised.

Now we will install a plain object in the method dictionary of our Demo class.

Evaluate `Demo methodDict at: #answer42 put: ObjectsAsMethodsExample new.`

Now try again to print the result of `Demo new answer42`. This time we get the answer 42.

If we take a look at the class `ObjectsAsMethodsExample` we will find the following methods:
16.7 Objects as method wrappers

```
answer42
^42

run: oldSelector with: arguments in: aReceiver
^self perform: oldSelector withArguments: arguments
```

When our Demo instance receives the message `answer42`, method lookup proceeds as usual, however the virtual machine will detect that in place of a compiled method, an ordinary Pharo object is trying to play this role. The VM will then send this object a new message `run:with:in:` with the original method selector, arguments and receiver as arguments. Since `ObjectsAsMethodsExample` implements this method, it intercepts the message and delegates it to itself.

We can now remove the fake method as follows:

```
[Demo methodDict removeKey: #answer42 ifAbsent: []]
```

If we take a closer look at `ObjectsAsMethodsExample`, we will see that its superclass also implements some methods like `flushcache`, `methodClass:` and `selector:`, but they are all empty. These messages may be sent to a compiled method, so they need to be implemented by an object pretending to be a compiled method. (`flushcache` is the most important method to be implemented; others may be required by some tools and depending on whether the method is installed using `Behavior>>addSelector:withMethod:` or directly using `MethodDictionary>>at:put:.`)

## Using method wrappers to perform test coverage

Method wrappers are a well-known technique for intercepting messages. In the original implementation(http://www.squeaksource.com/MethodWrappers.html), a method wrapper is an instance of a subclass of `CompiledMethod`. When installed, a method wrapper can perform special actions before or after invoking the original method. When uninstalled, the original method is returned to its rightful position in the method dictionary.

In Pharo, method wrappers can be implemented more easily by implementing `run:with:in:` instead of by subclassing `CompiledMethod`. In fact, there exists a lightweight implementation of objects as method wrappers(http://www.squeaksource.com/ObjectsAsMethodsWrap.html), but it is not part of standard Pharo at the time of this writing.

Nevertheless, the Pharo Test Runner uses precisely this technique to evaluate test coverage. Let's have a quick look at how it works.

The entry point for test coverage is the method `TestRunner>>runCoverage`:

```
TestRunner >> runCoverage
| packages methods |
... "identify methods to check for coverage"
self collectCoverageFor: methods
```
The method `TestRunner>>collectCoverageFor:` clearly illustrates the coverage checking algorithm:

```
TestRunner >> collectCoverageFor: methods
  | wrappers suite |
wrappers := methods collect: [ :each | TestCoverage on: each ].
suite := self
    resetResult;
suiteForAllSelected.

[ wrappers do: [ :each | each install ].
[ self runSuite: suite ] ensure: [ wrappers do: [ :each | each uninstall ] ] ] valueUnpreemptively.

wrappers := wrappers reject: [:each | each hasRun].
wrappers := wrappers collect: [:each | each reference].
wrappers empty
    ifTrue: [ UIManager default inform: 'Congratulations. Your tests cover all code under analysis.' ]
    ifFalse: ...
```

A wrapper is created for each method to be checked, and each wrapper is installed. The tests are run, and all wrappers are uninstalled. Finally the user obtains feedback concerning the methods that have not been covered.

How does the wrapper itself work? The `TestCoverage` wrapper has three instance variables, `hasRun`, `reference` and `method`. They are initialized as follows:

```
TestCoverage class >> on: aMethodReference
    ^ self new initializeOn: aMethodReference

TestCoverage >> initializeOn: aMethodReference
    hasRun := false.
    reference := aMethodReference.
    method := reference compiledMethod
```

The `install` and `uninstall` methods simply update the method dictionary in the obvious way:

```
TestCoverage >> install
    reference actualClass methodDict
    at: reference selector
    put: self

TestCoverage >> uninstall
    reference actualClass methodDict
    at: reference selector
    put: method
```

The `run:with:in:` method simply updates the `hasRun` variable, uninstalls the wrapper (since coverage has been verified), and resends the message to the
original method.

```groovy
run: aSelector with: anArray in: aReceiver
    self mark; uninstall.
    ^ aReceiver withArgs: anArray executeMethod: method

mark
    hasRun := true
```

Take a look at `ProtoObject>>withArgs:executeMethod:` to see how a method displaced from its method dictionary can be invoked.

That's all there is to it!

Method wrappers can be used to perform any kind of suitable behaviour before or after the normal operation of a method. Typical applications are instrumentation (collecting statistics about the calling patterns of methods), checking optional pre- and post-conditions, and memoization (optionally caching computed values of methods).

## 16.8 Pragmas

A pragma is an annotation that specifies data about a program, but is not involved in the execution of the program. Pragmas have no direct effect on the operation of the method they annotate. Pragmas have a number of uses, among them:

*Information for the compiler:* pragmas can be used by the compiler to make a method call a primitive function. This function has to be defined by the virtual machine or by an external plug-in.

*Runtime processing:* Some pragmas are available to be examined at runtime.

Pragmas can be applied to a program's method declarations only. A method may declare one or more pragmas, and the pragmas have to be declared prior to any Smalltalk statement. Each pragma is in effect a static message send with literal arguments.

We briefly saw pragmas when we introduced primitives earlier in this chapter. A primitive is nothing more than a pragma declaration. Consider `<primitive: 173 error:ec>` as contained in `instVarAt:`. The pragma's selector is `primitive:error:` and its arguments is an immediate literal value, 173. The variable `ec` is an error code, filled by the VM in case the execution of the implementation on the VM side failed.

The compiler is probably the bigger user of pragmas. `SUunit` is another tool that makes use of annotations. `SUunit` is able to estimate the coverage of an application from a test unit. One may want to exclude some methods from the coverage. This is the case of the documentation method in `SplitJointTest` class:
```kotlin
SplitJoinTest class >> documentation
    <ignoreForCoverage>
    "self showDocumentation"

    ^ 'This package provides function.... '"
```

By simply annotating a method with the pragma `<ignoreForCoverage>` one can control the scope of the coverage.

As instances of the class ` Pragma`, pragmas are first class objects. A compiled method answers to the message pragmas. This method returns an array of pragmas.

```kotlin
(SplitJoinTest class >> #showDocumentation) pragmas.
>>> an Array(<ignoreForCoverage>)
� (Float>>#+) pragmas
>>> an Array(<primitive: 41>)
```

Methods defining a particular query may be retrieved from a class. The class side of `SplitJoinTest` contains some methods annotated with `<ignoreForCoverage>`:

```kotlin
 Pragma allNamed: #ignoreForCoverage in: SplitJoinTest class
>>> an Array(<ignoreForCoverage> <ignoreForCoverage>
<ignoreForCoverage>)
```

A variant of `allNamed:in:` may be found on the class side of ` Pragma`.

A pragma knows in which method it is defined (using `method`), the name of the method (`selector`), the class that contains the method (`methodClass`), its number of arguments (`numArgs`), about the literals the pragma has for arguments (`hasLiteral` and `hasLiteralSuchThat:`).

## 16.9 Chapter summary

Reflection refers to the ability to query, examine and even modify the metaobjects of the runtime system as ordinary objects.

* The `Inspector` uses `instVarAt:` and related methods to view private instance variables of objects.

* Send `Behavior>>allInstances` to query instances of a class.

* The messages `class`, `isKindOf:`, `respondsTo:` etc. are useful for gathering metrics or building development tools, but they should be avoided in regular applications: they violate the encapsulation of objects and make your code harder to understand and maintain.

* `SystemNavigation` is a utility class holding many useful queries for navigation and browsing the class hierarchy. For example, use `SystemNavigation default browseMethodsWithSourceString: 'pharo'`
matchCase:true. to find and browse all methods with a given source string. (Slow, but thorough!)

* Every Pharo class points to an instance of `MethodDictionary` which maps selectors to instances of `CompiledMethod`. A compiled method knows its class, closing the loop.

* `RGMethodDefinition` is a lightweight proxy for a compiled method, providing additional convenience methods, and used by many Pharo tools.

* `RBBrowserEnvironment`, part of the Refactoring Browser infrastructure, offers a more refined interface than `SystemNavigation` for querying the system, since the result of a query can be used as a the scope of a new query. Both GUI and programmatic interfaces are available.

* `thisContext` is a pseudo-variable that reifies the runtime stack of the virtual machine. It is mainly used by the debugger to dynamically construct an interactive view of the stack. It is also especially useful for dynamically determining the sender of a message.

* Intelligent breakpoints can be set using `haltIf`, taking a method selector as its argument. `haltIf` halts only if the named method occurs as a sender in the run-time stack.

* A common way to intercept messages sent to a given target is to use a minimal object as a proxy for that target. The proxy implements as few methods as possible, and traps all message sends by implementing `doesNotUnderstand:`. It can then perform some additional action and then forward the message to the original target.

* `Send become:` to swap the references of two objects, such as a proxy and its target.

* Beware, some messages, like `class` and `yourself` are never really sent, but are interpreted by the VM. Others, like `+`, `-` and `ifTrue:` may be directly interpreted or inlined by the VM depending on the receiver.

* Another typical use for overriding `doesNotUnderstand:` is to lazily load or compile missing methods.

* `doesNotUnderstand:` cannot trap `self-sends`.

* A more rigorous way to intercept messages is to use an object as a method wrapper. Such an object is installed in a method dictionary in place of a compiled method. It should implement `run:with:in:` which is sent by the VM when it detects an ordinary object instead of a compiled method in the method dictionary. This technique is used by the SUnit Test Runner to collect coverage data.
<figure><img src="image_185.png" /></figure>
Regular expressions in Pharo

Regular expressions are widely used in many scripting languages such as Perl, Python and Ruby. They are useful to identify strings that match a certain pattern, to check that input conforms to an expected format, and to rewrite strings to new formats. Pharo also supports regular expressions due to the Regex package contributed by Vassili Bykov. Regex is installed by default in Pharo. If you are using an older image that does not include Regex the Regex package, you can install it yourself from SqueakSource (http://www.squeaksource.com/Regex.html).

A regular expression<fnref n="1" /> is a pattern that matches a set of strings. For example, the regular expression 'h.*o' will match the strings 'ho', 'hiho' and 'hello', but it will not match 'hi' or 'yo'. We can see this in Pharo as follows:

<table><tr><td>'ho' matchesRegex: 'h.*o'</td></tr><tr><td>&gt;&gt;&gt; true</td></tr><tr><td>'hiho' matchesRegex: 'h.*o'</td></tr><tr><td>&gt;&gt;&gt; true</td></tr><tr><td>'hello' matchesRegex: 'h.*o'</td></tr><tr><td>&gt;&gt;&gt; true</td></tr><tr><td>'hi' matchesRegex: 'h.*o'</td></tr><tr><td>&gt;&gt;&gt; false</td></tr><tr><td>'yo' matchesRegex: 'h.*o'</td></tr><tr><td>&gt;&gt;&gt; false</td></tr></table>

<footnote n="1">¹http://en.wikipedia.org/wiki/Regular_expression</footnote>
In this chapter we will start with a small tutorial example in which we will develop a couple of classes to generate a very simple site map for a web site. We will use regular expressions

1. to identify HTML files,

2. to strip the full path name of a file down to just the file name,

3. to extract the title of each web page for the site map, and

4. to generate a relative path from the root directory of the web site to the HTML files it contains.

After we complete the tutorial example, we will provide a more complete description of the Regex package, based largely on Vassili Bykov's documentation provided in the package. (The original documentation can be found on the class side of `RxParser`.)

## 17.1 Tutorial example — generating a site map

Our job is to write a simple application that will generate a site map for a web site that we have stored locally on our hard drive. The site map will contain links to each of the HTML files in the web site, using the title of the document as the text of the link. Furthermore, links will be indented to reflect the directory structure of the web site.

### Accessing the web directory

**To do** If you do not have a web site on your machine, copy a few HTML files to a local directory to serve as a test bed.

We will develop two classes, `WebDir` and `WebPage`, to represent directories and web pages. The idea is to create an instance of `WebDir` which will point to the root directory containing our web site. When we send it the message `makeToc`, it will walk through the files and directories inside it to build up the site map. It will then create a new file, called `toc.html`, containing links to all the pages in the web site.

One thing we will have to watch out for: each `WebDir` and `WebPage` must remember the path to the root of the web site, so it can properly generate links relative to the root.

**To do** Define the class `WebDir` with instance variables `webDir` and `homePath`, and define the appropriate initialization method.

Also define class-side methods to prompt the user for the location of the web site on your computer, as follows:
<figure><img src="image_186.png" /><figcaption>Figure 17.1: A WebDir instance.</figcaption></figure>

```kotlin
WebDir >> setDir: dir home: path
webDir := dir.
homePath := path

WebDir class >> onDir: dir
^ self new setDir: dir home: dir pathString

WebDir class >> selectHome
^ self onDir: UIManager default chooseDirectory
```

The last method opens a browser to select the directory to open. Now, if you inspect the result of `WebDir selectHome`, you will be prompted for the directory containing your web pages, and you will be able to verify that `webDir` and `homePath` are properly initialized to the directory holding your web site and the full path name of this directory.

It would be nice to be able to programmatically instantiate a `WebDir`, so let's add another creation method.

**To do** Add the following methods and try it out by inspecting the result of `WebDir onPath: 'path to your web site'`.

```kotlin
WebDir class>>onPath: homePath
^ self onPath: homePath home: homePath

WebDir class>>onPath: path home: homePath
^ self new setDir: path asFileReference home: homePath
```

## Pattern matching HTML files

So far so good. Now we would like to use regexes to find out which HTML files this web site contains.
If we browse the `FileDirectory` class, we find that the method `fileNames` will list all the files in a directory. We want to select just those with the file extension `.html`. The regex that we need is `'.*\.html'`. The first dot will match any character except a newline:

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

The `*` (known as the *Kleene star*, after Stephen Kleene, who invented it) is a regex operator that will match the preceding regex any number of times (including zero).

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

Since the dot is a special character in regexes, if we want to literally match a dot, then we must escape it.

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

Now let's check our regex to find HTML files works as expected.

<figure><img src="image_190.png" /></figure>
```groovy
'index.htm' matchesRegex: '.*\.html'
>>> false
```

Looks good. Now let's try it out in our application.

**To do** Add the following method to WebDir and try it out on your test web site.

```groovy
WebDir >> htmlFiles
    ^ webDir fileNames select: [ :each | each matchesRegex: '.*\.html' ]
```

If you send htmlFiles to a WebDir instance and print it, you should see something like this:

```text
(WebDir onPath: '...' htmlFiles
>>> #('index.html' ...)
```

## Caching the regex

Now, if you browse `matchesRegex:`, you will discover that it is an extension method of `String` that creates a fresh instance of `RxParser` every time it is sent. That is fine for ad hoc queries, but if we are applying the same regex to every file in a web site, it is smarter to create just one instance of `RxParser` and reuse it. Let's do that.

**To do** Add a new instance variable `htmlRegex` to WebDir and initialize it by sending `asRegex` to our regex string. Modify `WebDir>>htmlFiles` to use the same regex each time as follows:

```groovy
WebDir >> initialize
    htmlRegex := '.*\.html' asRegex
```

```groovy
WebDir >> htmlFiles
    ^ webDir fileNames select: [ :each | htmlRegex matches: each ]
```

Now listing the HTML files should work just as it did before, except that we reuse the same regex object many times.

## Accessing web pages

Accessing the details of individual web pages should be the responsibility of a separate class, so let's define it, and let the `WebDir` class create the instances.

**To do** Define a class `WebPage` with instance variables `path`, to identify the HTML file, and `homePath`, to identify the root directory of the web site. (We will need this to correctly generate links from the root of the web site to the files it contains.) Define an initialization method on the instance side and a creation method on the class side.
```pharo
[ WebPage >> initializePath: filePath homePath: dirPath
    path := filePath.
    homePath := dirPath
]

WebPage class >> on: filePath forHome: homePath
    ^ self new initializePath: filePath homePath: homePath
```

A WebDir instance should be able to return a list of all the web pages it contains.

**To do** Add the following method to WebDir, and inspect the return value to verify that it works correctly.

```pharo
WebDir >> webPages
    ^ self htmlFiles collect:
        [ :each | WebPage
            on: webDir pathString, '/', each
            forHome: homePath ]
```

You should see something like this:

```
(WebDir onPath: '...' webPages
>>> an Array(a WebPage a WebPage ...)
```

## String substitutions

That's not very informative, so let's use a regex to get the actual file name for each web page. To do this, we want to strip away all the characters from the path name up to the last directory. On a Unix file system directories end with a slash (/), so we need to delete everything up to the last slash in the file path.

The String extension method copyWithRegex:matchesReplacedWith: does what we want:

```
['hello' copyWithRegex: '[elo]+' matchesReplacedWith: 'i'
>>> 'hi'
```

In this example the regex `[elo]` matches any of the characters e, l or o. The operator `+` is like the Kleene star, but it matches exactly *one* or more instances of the regex preceding it. Here it will match the entire substring 'ello' and replay it in a fresh string with the letter i.

**To do** Add the following method and verify that it works as expected.

```pharo
WebPage >> filename
    ^ path copyWithRegex: '.*/' matchesReplacedWith: ''
```

Now you should see something like this on your test web site:

```
(WebDir onPath: '...' webPages collect: [:each | each filename]
>>> #( 'index.html' ...)
```
## Extracting regex matches

Our next task is to extract the title of each HTML page. First we need a way to get at the contents of each page. This is straightforward.

### To do
Add the following method and try it out.

```java
WebPage >> contents
    ^ (FileStream oldFileOrNoneNamed: path) contents
```

Actually, you might have problems if your web pages contain non-ascii characters, in which case you might be better off with the following code:

```java
WebPage >> contents
    ^ (FileStream oldFileOrNoneNamed: path)
        converter: Latin1TextConverter new;
        contents
```

You should now be able to see something like this:

```xml
(WebDir onPath: '...' webPages first contents
>>> '<head>
<title>Home Page</title>
...
'
```

Now let's extract the title. In this case we are looking for the text that occurs between the HTML tags `<title>` and `</title>`.

What we need is a way to extract part of the match of a regular expression. Subexpressions of regexes are delimited by parentheses. Consider the regex `([CARETaeiou]+)([aeiou]+)`; it consists of two subexpressions, the first of which will match a sequence of one or more non-vowels, and the second of which will match one or more vowels: the operator `CARET` at the start of a bracketed set of characters negates the set. (NB: In Pharo the caret is also the return keyword, which we write as `^`. To avoid confusion, we will write `CARET` when we are using the caret within regular expressions to negate sets of characters, but you should not forget, they are actually the same thing.) Now we will try to match a prefix of the string 'pharo' and extract the submatches:

```text
| re |
re := '([CARETaeiou]+)([aeiou]+)' asRegex.
re matchesPrefix: 'pharo'
>>> true
re subexpression: 1
>>> 'pha'
re subexpression: 2
>>> 'ph'
re subexpression: 3
>>> 'a'
```
After successfully matching a regex against a string, you can always send it the message `subexpression: 1` to extract the entire match. You can also send `subexpression: n` where n-1 is the number of subexpressions in the regex. The regex above has two subexpressions, numbered 2 and 3.

We will use the same trick to extract the title from an HTML file.

### To do Define the following method:

```ruby
WebPage >> title
| re |
re := '[\w\W]*<title>(.*)</title>' asRegexIgnoringCase.
^ (re matchesPrefix: self contents)
    ifTrue: [ re subexpression: 2 ]
    ifFalse: [ '(', self文件Name, ' -- untitled)' ]
```

There are a couple of subtle points to notice here. First, HTML does not care whether tags are upper or lower case, so we must make our regex case insensitive by instantiating it with `asRegexIgnoringCase`.

Second, since dot matches any character except a newline, the regex `.*<title>(.*)</title>` will not work as expected if multiple lines appear before the title. The regex `\w` matches any alphanumeric, and `\W` will match any non-alphanumeric, so `[\w\W]` will match any character including newlines. (If we expect titles to possible contain newlines, we should play the same trick with the subexpression.)

Now we can test our title extractor, and we should see something like this:

```text
(WebDir onPath: '...' webPages first title
>>> 'Home page'
```

## More string substitutions

In order to generate our site map, we need to generate links to the individual web pages. We can use the document title as the name of the link. We just need to generate the right path to the web page from the root of the web site. Luckily this is trivial — it is simple the full path to the web page minus the full path to the root directory of the web site.

We must only watch out for one thing. Since the `homePath` variable does not end in a `/`, we must append one, so that relative path does not include a leading `/`. Notice the difference between the following two results:

```text
'/home/testweb/index.html' copyWithRegex: '/home/testweb'
matchesReplacedWith: ''
>>> '/index.html'

'/home/testweb/index.html' copyWithRegex: '/home/testweb/'
matchesReplacedWith: ''
>>> 'index.html'
```
<figure><img src="image_191.png" /><figcaption>Figure 17.2: A small site map.</figcaption></figure>

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

Now we can generate a table of contents for an arbitrary web directory!

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

## 17.2 Regex syntax

We will now have a closer look at the syntax of regular expressions as supported by the Regex package.

The simplest regular expression is a single character. It matches exactly that character. A sequence of characters matches a string with exactly the same sequence of characters:

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

Operators are applied to regular expressions to produce more complex regular expressions. Sequencing (placing expressions one after another) as an operator is, in a certain sense, invisible — yet it is arguably the most common.
We have already seen the Kleene star (`*`) and the `+` operator. A regular expression followed by an asterisk matches any number (including 0) of matches of the original expression. For example:

```
['ab' matchesRegex: 'a*b'
>>> true

['aaaaab' matchesRegex: 'a*b'
>>> true

['b' matchesRegex: 'a*b'
>>> true

['aac' matchesRegex: 'a*b'
>>> false "b does not match"
```

The Kleene star has higher precedence than sequencing. A star applies to the shortest possible subexpression that precedes it. For example, `ab*` means a followed by zero or more occurrences of `b`, not zero or more occurrences of `ab`:

```
['abbb' matchesRegex: 'ab*'
>>> true

['abab' matchesRegex: 'ab*'
>>> false
```

To obtain a regex that matches zero or more occurrences of `ab`, we must enclose `ab` in parentheses:

```
['abab' matchesRegex: '(ab)*'
>>> true

['abcab' matchesRegex: '(ab)*'
>>> false "c spoils the fun"
```

Two other useful operators similar to `*` are `+` and `?`. `+` matches one or more instances of the regex it modifies, and `?` will match zero or one instance.

```
['ac' matchesRegex: 'ab*c'
>>> true

['ac' matchesRegex: 'ab+c'
>>> false "need at least one b"

['abbc' matchesRegex: 'ab+c'
>>> true

['abbc' matchesRegex: 'ab?c'
>>> false "too many b's"
```

As we have seen, the characters `*`, `+`, `?`, `(`, and `)` have special meaning within regular expressions. If we need to match any of them literally, it should be escaped by preceding it with a backslash `\`. Thus, backslash is also special character, and needs to be escaped for a literal match. The same holds for all further special characters we will see.
```
['ab*' matchesRegex: 'ab*'
>>> false "star in the right string is special"

['ab*' matchesRegex: 'ab\*'
>>> true

['a\c' matchesRegex: 'a\c'
>>> true
```

The last operator is `|`, which expresses choice between two subexpressions. It matches a string if either of the two subexpressions matches the string. It has the lowest precedence — even lower than sequencing. For example, `ab*|ba*` means a followed by any number of b's, or b followed by any number of a's:

```
['abb' matchesRegex: 'ab*|ba*'
>>> true

['baa' matchesRegex: 'ab*|ba*'
>>> true

['baab' matchesRegex: 'ab*|ba*'
>>> false
```

A bit more complex example is the expression `c(a|d)+r`, which matches the name of any of the Lisp-style car, cdr, caar, cadr, ... functions:

```
['car' matchesRegex: 'c(a|d)+r'
>>> true

['cdr' matchesRegex: 'c(a|d)+r'
>>> true

['cadr' matchesRegex: 'c(a|d)+r'
>>> true
```

It is possible to write an expression that matches an empty string, for example the expression `a|` matches an empty string. However, it is an error to apply `*`, `+`, or `?` to such an expression: `(a|)*` is invalid.

So far, we have used only characters as the *smallest* components of regular expressions. There are other, more interesting, components. A character set is a string of characters enclosed in square brackets. It matches any single character if it appears between the brackets. For example, `[01]` matches either `0` or `1`:

```
['0' matchesRegex: '[01]'
>>> true

['3' matchesRegex: '[01]'
>>> false

['11' matchesRegex: '[01]'
>>> false "a set matches only one character"
```

Using plus operator, we can build the following binary number recognizer:
```python
'10010100' matchesRegex: '[01]+'
>>> true

'10001210' matchesRegex: '[01]+'
>>> false
```

If the first character after the opening bracket is `CARET`, the set is inverted: it matches any single character *not* appearing between the brackets:

```python
'0' matchesRegex: '[CARET01]'
>>> false

'3' matchesRegex: '[CARET01]'
>>> true
```

For convenience, a set may include ranges: pairs of characters separated by a hyphen (-). This is equivalent to listing all characters in between: `'[0-9]'` is the same as `'[0123456789]'`. Special characters within a set are `CARET`, `-`, and `]`, which closes the set. Below are examples how to literally match them in a set:

```python
'CARET' matchesRegex: '[01CARET]'
>>> true "put the caret anywhere except the start"

'-' matchesRegex: '[01-]'
>>> true "put the hyphen at the end"

']' matchesRegex: ']01]'
>>> true "put the closing bracket at the start"
```

Thus, empty and universal sets cannot be specified.

## Character classes

Regular expressions can also include the following backquote escapes to refer to popular classes of characters: `\w` to match alphanumeric characters, `\d` to match digits, and `\s` to match whitespace. Their upper-case variants, `\W`, `\D` and `\S`, match the complementary characters (non-alphanumerics, non-digits and non-whitespace). Here is a summary of the syntax seen so far:
<table><thead><tr><td>Syntax</td><td>What it represents</td></tr></thead><tbody><tr><td>a</td><td>literal match of character a</td></tr><tr><td>.</td><td>match any char (except newline)</td></tr><tr><td>(...)</td><td>group subexpression</td></tr><tr><td>\x</td><td>escape the following special character where 'x' can be 'w','s','d','W','S','D'</td></tr><tr><td>*</td><td>Kleene star — match previous regex zero or more times</td></tr><tr><td>+</td><td>match previous regex one or more times</td></tr><tr><td>?</td><td>match previous regex zero times or once</td></tr><tr><td>|</td><td>match choice of left and right regex</td></tr><tr><td>[abcd]</td><td>match choice of characters abcd</td></tr><tr><td>[^abcd]</td><td>match negated choice of characters</td></tr><tr><td>[0-9]</td><td>match range of characters 0 to 9</td></tr><tr><td>\w</td><td>match alphanumeric</td></tr><tr><td>\W</td><td>match non-alphanumeric</td></tr><tr><td>\d</td><td>match digit</td></tr><tr><td>\D</td><td>match non-digit</td></tr><tr><td>\s</td><td>match space</td></tr><tr><td>\S</td><td>match non-space</td></tr></tbody></table>

As mentioned in the introduction, regular expressions are especially useful for validating user input, and character classes turn out to be especially useful for defining such regexes. For example, non-negative numbers can be matched with the regex `\d+`:

```
'42' matchesRegex: '\d+'
>>> true
```

```
'-1' matchesRegex: '\d+'
>>> false
```

Better yet, we might want to specify that non-zero numbers should not start with the digit 0:

```
'0' matchesRegex: '0|([1-9]\d*)'
>>> true
```

```
'1' matchesRegex: '0|([1-9]\d*)'
>>> true
```

```
'42' matchesRegex: '0|([1-9]\d*)'
>>> true
```

```
'099' matchesRegex: '0|([1-9]\d*)'
>>> false "leading 0"
```

We can check for negative and positive numbers as well:

```
'0' matchesRegex: '(0|((\+|-)?[1-9]\d*))'
>>> true
```
Note that these elements are components of the character classes, i.e., they have to be enclosed in an extra set of square brackets to form a valid regular expression. For example, a non-empty string of digits would be represented as `[[:digit:]]+`. The above primitive expressions and operators are common to many implementations of regular expressions.

```
[ '42' matchesRegex: '[[:digit:]]+'
>>> true
```

## Special character classes

The next primitive expression is unique to this Smalltalk implementation. A sequence of characters between colons is treated as a unary selector which is supposed to be understood by characters. A character matches such an expression if it answers true to a message with that selector. This allows a more readable and efficient way of specifying character classes. For example, `[0-9]` is equivalent to `:isDigit:`, but the latter is more efficient. Analogously to character sets, character classes can be negated: `:CARETisDigit:` matches a character that answers false to `isDigit`, and is therefore equivalent to `[CARET0-9]`.

So far we have seen the following equivalent ways to write a regular expression that matches a non-empty string of digits: `[0-9]+`, `\d+`, `\d]+`, `[[:digit:]]+`, `:isDigit:+`.

```
[ '42' matchesRegex: '[0-9]+'
>>> true
```

```
[ '42' matchesRegex: '\d+'
>>> true
```

```
[ '42' matchesRegex: '[\d]+'
>>> true
```

```
[ '42' matchesRegex: '[[:digit:]]+'
>>> true
```

```
[ '42' matchesRegex: ':isDigit:+'
>>> true
```

## Matching boundaries

The last group of special primitive expressions shown next is used to match boundaries of strings.
<table><thead><tr><td>Syntax</td><td>What it represents</td></tr></thead><tbody><tr><td>CARET</td><td>match an empty string at the beginning of a line</td></tr><tr><td>\$</td><td>match an empty string at the end of a line</td></tr><tr><td>\b</td><td>match an empty string at a word boundary</td></tr><tr><td>\B</td><td>match an empty string not at a word boundary</td></tr><tr><td>\<</td><td>match an empty string at the beginning of a word</td></tr><tr><td>\>\</td><td>match an empty string at the end of a word</td></tr></tbody></table>

'hello world' matchesRegex: '.*\bw.*'
>>> true "word boundary before w"

'hello world' matchesRegex: '.*\bo.*'
>>> false "no boundary before o"

## 17.3 Regex API

Up to now we have focussed mainly on the syntax of regexes. Now we will have a closer look at the different messages understood by strings and regexes.

### Matching prefixes and ignoring case

So far most of our examples have used the String extension method `matchesRegex:.`.

Strings also understand the following messages: `prefixMatchesRegex:`, `matchesRegexIgnoringCase:` and `prefixMatchesRegexIgnoringCase:`.

The message `prefixMatchesRegex:` is just like `matchesRegex`, except that the whole receiver is not expected to match the regular expression passed as the argument; matching just a prefix of it is enough.

'abacus' matchesRegex: '(a|b)+'
>>> false

'abacus' prefixMatchesRegex: '(a|b)+'
>>> true

'ABBA' matchesRegexIgnoringCase: '(a|b)+'
>>> true

'Abacus' matchesRegexIgnoringCase: '(a|b)+'
>>> false

'Abacus' prefixMatchesRegexIgnoringCase: '(a|b)+'
>>> true
Enumeration interface

Some applications need to access *all* matches of a certain regular expression within a string. The matches are accessible using a protocol modeled after the familiar *Collection*-like enumeration protocol.

regex:matchesDo: evaluates a one-argument aBlock for every match of the regular expression within the receiver string.

| list |
list := OrderedCollection new.
'Jack meet Jill' regex: '\w+' matchesDo: [:word | list add: word].
list
>>> an OrderedCollection('Jack' 'meet' 'Jill')

regex:matchesCollect: evaluates a one-argument aBlock for every match of the regular expression within the receiver string. It then collects the results and answers them as a SequenceableCollection.

'Jack meet Jill' regex: '\w+' matchesCollect: [:word | word size]
>>> an OrderedCollection(4 4 4)

allRegexMatches: returns a collection of all matches (substrings of the
receiver string) of the regular expression.

'Jack and Jill went up the hill' allRegexMatches: '\w+'
>>> an OrderedCollection('Jack' 'and' 'Jill' 'went' 'up' 'the' 'hill')

Replacement and translation

It is possible to replace all matches of a regular expression with a certain
string using the message copyWithRegex:matchesReplacedWith:.

'Krazy hates Ignatz' copyWithRegex: '\<[[[:lower:]]+\>'
matchesReplacedWith: 'loves'
>>> 'Krazy loves Ignatz'

A more general substitution is match translation. This message evaluates a
block passing it each match of the regular expression in the receiver string
and answers a copy of the receiver with the block results spliced into it in
place of the respective matches.

'Krazy loves Ignatz' copyWithRegex: '\b[a-z]+\b'
matchesTranslatedUsing: [:each | each asUppercase]
>>> 'Krazy LOVES Ignatz'

All messages of enumeration and replacement protocols perform a case-
sensitive match. Case-insensitive versions are not provided as part of a String
protocol. Instead, they are accessible using the lower-level matching interface
presented in the following section.
## Lower-level interface

When you send the message `matchesRegex:` to a string, the following happens:

* A fresh instance of `RxParser` is created, and the regular expression string is passed to it, yielding the expression's syntax tree.

* The syntax tree is passed as an initialization parameter to an instance of `RxMatcher`. The instance sets up some data structure that will work as a recognizer for the regular expression described by the tree.

* The original string is passed to the matcher, and the matcher checks for a match.

## The Matcher

If you repeatedly match a number of strings against the same regular expression using one of the messages defined in `String`, the regular expression string is parsed and a new matcher is created for every match. You can avoid this overhead by building a matcher for the regular expression, and then reusing the matcher over and over again. You can, for example, create a matcher at a class or instance initialization stage, and store it in a variable for future use. You can create a matcher using one of the following methods:

* You can send `asRegex` or `asRegexIgnoringCase` to the string.

* You can directly invoke the `RxMatcher` constructor methods `forString:` or `forString:ignoreCase:` (which is what the convenience methods above will do).

Here we send `matchesIn:` to collect all the matches found in a string:

```
| octal |
octal := '8r[0-9A-F]+' asRegex.
octal matchesIn: '8r52 = 16r2A'
>>> an OrderedCollection('8r52')
```

```
| hex |
hex := '16r[0-9A-F]+' asRegexIgnoringCase.
hex matchesIn: '8r52 = 16r2A'
>>> an OrderedCollection('16r2A')
```

```
| hex |
hex := RxMatcher forString: '16r[0-9A-F-f]+' ignoreCase: true.
hex matchesIn: '8r52 = 16r2A'
>>> an OrderedCollection('16r2A')
```

## Matching

A matcher understands these messages (all of them return true to indicate successful match or search, and false otherwise):
**matches**: aString — true if the whole argument string (aString) matches.

```text
'\w+' asRegex matches: 'Krazy'
>>> true
```

**matchesPrefix**: aString — true if some prefix of the argument string (not necessarily the whole string) matches.

```text
'\w+' asRegex matchesPrefix: 'Ignatz hates Krazy'
>>> true
```

**search**: aString — Search the string for the first occurrence of a matching substring. Note that the first two methods only try matching from the very beginning of the string. Using the above example with a matcher for a+, this method would answer success given a string 'baaa', while the previous two would fail.

```text
'\b[a-z]+\b' asRegex search: 'Ignatz hates Krazy'
>>> true "finds 'hates'"
```

The matcher also stores the outcome of the last match attempt and can report it: lastResult answers a Boolean: the outcome of the most recent match attempt. If no matches were attempted, the answer is unspecified.

```text
| number |
number := '\d+' asRegex.
number search: 'Ignatz throws 5 bricks'.
number lastResult
>>> true
```

**matchesStream**, **matchesStreamPrefix**: and **searchStream**: are analogous to the above three messages, but takes streams as their argument.

```text
| ignatz names |
ignatz := ReadStream on: 'Ignatz throws bricks at Krazy'.
names := '\<[A-Z][a-z]+\>' asRegex.
names matchesStreamPrefix: ignatz
>>> true
```

## Subexpression matches

After a successful match attempt, you can query which part of the original string has matched which part of the regex. A subexpression is a parenthesized part of a regular expression, or the whole expression. When a regular expression is compiled, its subexpressions are assigned indices starting from 1, depth-first, left-to-right.

For example, the regex `((\d+)\s*(\w+))` has four subexpressions, including itself.

```text
1: ((\d+)\s*(\w+)) "the complete expression"
2: (\d+)\s*(\w+) "top parenthesized subexpression"
```
3: \d+ "first leaf subexpression"

4: \w+ "second leaf subexpression"

The highest valid index is equal to 1 plus the number of matching parentheses.
(So, 1 is always a valid index, even if there are no parenthesized subexpressions.)

After a successful match, the matcher can report what part of the original
string matched what subexpression. It understands these messages:

subexpressionCount answers the total number of subexpressions: the highest
value that can be used as a subexpression index with this matcher. This value
is available immediately after initialization and never changes.

subexpression: takes a valid index as its argument, and may be sent only
after a successful match attempt. The method answers a substring of the
original string the corresponding subexpression has matched to.

subBeginning: and subEnd: answer the positions within the argument string
or stream where the given subexpression match has started and ended, respectively.

| items |

items := '((\d+)\s*(\w+))' asRegex.

items search: 'Ignatz throws 1 brick at Krazy'.

items subexpressionCount

>>> 4

items subexpression: 1

>>> '1 brick' "complete expression"

items subexpression: 2

>>> '1 brick' "top subexpression"

items subexpression: 3

>>> '1' "first leaf subexpression"

items subexpression: 4

>>> 'brick' "second leaf subexpression"

items subBeginning: 3

>>> 14

items subEnd: 3

>>> 15

items subBeginning: 4

>>> 16

items subEnd: 4

>>> 21

As a more elaborate example, the following piece of code uses a MMM DD, YYYY
date format recognizer to convert a date to a three-element array with year,
month, and day strings:

| date result |

date :=

'(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(\d\d?)\s*, \s*19(\d\d)'
```pharo
result := (date matches: 'Aug 6, 1996')
    ifTrue: [{ (date subexpression: 4) .
            (date subexpression: 2) .
            (date subexpression: 3) } ]
    ifFalse: ['no match'].
result
>>> #( '96' 'Aug' '6')
```

## Enumeration and Replacement

The String enumeration and replacement protocols that we saw earlier in this section are actually implemented by the matcher. RxMatcher implements the following methods for iterating over matches within strings: `matchesIn:`, `matchesIn:do:`, `matchesIn:collect:`, `copy:replacingMatchesWith:` and `copy:translatingMatchesUsing:`.

```pharo
| seuss aWords |
seuss := 'The cat in the hat is back'.
aWords := '\<([^aeiou][a])+\>' asRegex. "match words with 'a' in them"
aWords matchesIn: seuss
>>> an OrderedCollection('cat' 'hat' 'back')
aWords matchesIn: seuss collect: [:each | each asUppercase ]
>>> an OrderedCollection('CAT' 'HAT' 'BACK')
aWords copy: seuss replacingMatchesWith: 'grinch'
>>> 'The grinch in the grinch is grinch'
aWords copy: seuss translatingMatchesUsing: [ :each | each asUppercase ]
>>> 'The CAT in the HAT is BACK'
```

There are also the following methods for iterating over matches within streams: `matchesOnStream:`, `matchesOnStream:do:`, `matchesOnStream:collect:`, `copyStream:to:replacingMatchesWith:` and `copyStream:to:translatingMatchesUsing:`.

## Error Handling

Several exceptions may be raised by `RxParser` when building regexes. The exceptions have the common parent `RegexError`. You may use the usual Smalltalk exception handling mechanism to catch and handle them.

* `RegexSyntaxError` is raised if a syntax error is detected while parsing a

* `regex RegexCompilationError` is raised if an error is detected while

* building a matcher `RegexMatchingError` is raised if an error occurs while

* matching (for example, if a bad selector was specified using `':<selector>`: ')

* syntax, or because of the matcher's internal error).
```groovy
[ '+ ' asRegex] on: RegexError do: [:ex | ^ ex printString ]
>>> 'RegexSyntaxError: nullable closure'
```

## 17.4 Implementation Notes by Vassili Bykov

**What to look at first.** In 90% of the cases, the method `String>>matches-Regex:` is all you need to access the package.

`RxParser` accepts a string or a stream of characters with a regular expression, and produces a syntax tree corresponding to the expression. The tree is made of instances of `Rxs*` classes.

`RxMatcher` accepts a syntax tree of a regular expression built by the parser and compiles it into a matcher: a structure made of instances of `Rxm*` classes. The `RxMatcher` instance can test whether a string or a positionable stream of characters matches the original regular expression, or it can search a string or a stream for substrings matching the expression. After a match is found, the matcher can report a specific string that matched the whole expression, or any parenthesized subexpression of it. All other classes support the same functionality and are used by `RxParser`, `RxMatcher`, or both.

**Caveats** The matcher is similar in spirit, but *not* in design to Henry Spencer's original regular expression implementation in C. The focus is on simplicity, not on efficiency. I didn't optimize or profile anything. The matcher passes H. Spencer's test suite (see `test suite` protocol), with quite a few extra tests added, so chances are good there are not too many bugs. But watch out anyway.

**Acknowledgments** Since the first release of the matcher, thanks to the input from several fellow Smalltalkers, I became convinced a native Smalltalk regular expression matcher was worth the effort to keep it alive. For the advice and encouragement that made this release possible, I want to thank: Felix Hack, Eliot Miranda, Robb Shecter, David N. Smith, Francis Wolinski and anyone whom I haven't yet met or heard from, but who agrees this has not been a complete waste of time.

## 17.5 Chapter Summary

Regular expressions are an essential tool for manipulating strings in a trivial way. This chapter presented the `Regex` package for `Pharo`. The essential points of this chapter are:

* For simple matching, just send `matchesRegex:` to a string

* When performance matters, send `asRegex` to the string representing the regex, and reuse the resulting matcher for multiple matches
* Subexpression of a matching regex may be easily retrieved to an arbitrary depth

* A matching regex can also replace or translate subexpressions in a new copy of the string matched

* An enumeration interface is provided to access all matches of a certain regular expression

* Regexes work with streams as well as with strings.