Chapter 1
A quick tour of Pharo

In this chapter we will give you a high-level tour of Pharo to help you get comfortable with the environment. There will be plenty of opportunities to try things out, so it would be a good idea if you have a computer handy when you read this chapter.

We will use this icon: PIC to mark places in the text where you should try something out in Pharo. In particular, you will fire up Pharo, learn about the different ways of interacting with the system, and discover some of the basic tools. You will also learn how to define a new method, create an object and send it messages.

1.1 Getting started

Pharo is available as a free download from http://pharo-project.org. There are three parts that you will need to download, consisting of four files (see Figure 1.1).


PIC

Figure 1.1: The Pharo download files for one of the supported platforms.


1.
The virtual machine (VM) is the only part of the system that is different for each operating system and processor. Pre-compiled virtual machines are available for all the major computing environments. In Figure 1.1 we see the VM for the selected platform is called Pharo.exe.
2.
The sources file contains the source code for all of the parts of Pharo that don’t change very frequently. In Figure 1.1 it is called SqueakV39.sources.1
3.
The current system image is a snapshot of a running Pharo system, frozen in time. It consists of two files: an .image file, which contains the state of all of the objects in the system (including classes and methods, since they are objects too), and a .changes file, which contains a log of all of the changes to the source code of the system. In Figure 1.1, these files are called pharo.image and pharo.changes.

PIC Download and install Pharo on your computer.

We recommend that you use the image provided on the Pharo by Example web page.2

Most of the introductory material in this book will work with any version, so if you already have one installed, you may as well continue to use it. However, if you notice differences between the appearance or behaviour of your system and what is described here, do not be surprised.

As you work in Pharo, the image and changes files are modified, so you need to make sure that they are writable. Always keep these two files together. Never edit them directly with a text editor, as Pharo uses them to store the objects you work with and to log the changes you make to the source code. It is a good idea to keep a backup copy of the downloaded image and changes files so you can always start from a fresh image and reload your code.

The sources file and the VM can be read-only — they can be shared between different users. All of these files can be placed in the same directory, but it is also possible to put the Virtual Machine and sources file in separate directory where everyone has access to them. Do whatever works best for your style of working and your operating system.


PIC

Figure 1.2: A fresh http://PharoByExample.org image.


Launching. To start Pharo, do whatever your operating system expects: drag the .image file onto the icon of the virtual machine, or double-click the .image file, or at the command line type the name of the virtual machine followed by the path to the .image file. (When you have multiple VMs installed on your machine the operating system may not automatically pick the right one; in this case it is safer to drag and drop the image onto the virtual machine, or to use the command line.) Once Pharo is running, you should see a single large window, possibly containing some open workspace windows (see Figure 1.2), and it’s not obvious how to proceed! You might notice a menu bar, but Pharo mainly makes use of context-dependent pop-up menus. PIC Start Pharo. You can dismiss any open workspaces by clicking on the red button in the top left corner of the workspace window. You can minimize windows (so that they move to the dock on the bottom of the screen) by clicking on the orange button. Clicking on the green button will cause the window to take up the entire screen. First Interaction. A good place to get started is the world menu shown in Figure 1.3 (a). PIC Click with the mouse on the background of the main window to show the world menu, then choose Workspace to create a new workspace.
PIC
(a) The world menu
PIC
(b) The contextual menu
PIC
(c) The morphic halo

Figure 1.3: The world menu (brought up by clicking), a contextual menu (action-clicking), and a morphic halo (meta-clicking).

Smalltalk was originally designed for a computer with a three button mouse. If your mouse has fewer than three buttons, you will have to press extra keys while clicking the mouse to simulate the extra buttons. A two-button mouse works quite well with Pharo, but if you have only a single-button mouse, you should seriously consider buying a two-button mouse with a clickable scroll wheel: it will make working with Pharo much more pleasant. Pharo avoids terms like “left mouse click” because different computers, mice, keyboards and personal configurations mean that different users will need to press different physical buttons to achieve the same effect. Originally Smalltalk introduced colours to stand for the different mouse buttons.3 Since many users will use various modifiers keys (control, ALT, meta etc.) to achieve the same effect, we will instead use the following terms:
click:
this is the most often used mouse button, and is normally equivalent to clicking a single-mouse button without any modifier key; click on the image to bring up the “World” menu (Figure 1.3 (a)).
action-click:
this is the next most used button; it is used to bring up a contextual menu, that is, a menu that offers different sets of actions depending on where the mouse is pointing; see Figure 1.3 (b). If you do not have a multi-button mouse, then normally you will configure the control modifier key to action-click with the mouse button.
meta-click:
Finally, you may meta-click on any object displayed in the image to activate the “morphic halo”, an array of handles that are used to perform operations on the on-screen objects themselves, such as rotating them or resizing them; see Figure 1.3 (c).4 If you let the mouse linger over a handle, a help balloon will explain its function. In Pharo, how you meta-click depends on your operating system: either you must hold SHIFT ctrl or SHIFT option while clicking.

PIC Type Time now in the workspace. Now action-click in the workspace. Select print it .

We recommend that right-handed people configure their mouse to click with the left button, action-click with the right button, and meta-click with the clickable scroll wheel, if one is available. If you are using a Macintosh without a second mouse button, you can simulate one by holding down the PIC key while clicking the mouse. However, if you are going to be using Pharo at all often, we recommend investing in a mouse with at least two buttons.

You can configure your mouse to work the way you want by using the preferences of your operating system and mouse driver. Pharo has some preferences for customising the mouse and the meta keys on your keyboard. In the preference browser ( System Preferences Preference Browser), the keyboard category contains an option swapControlAndAltKeys that switches the action-click and meta-click functions. There are also options to duplicate the various command keys.


PIC

Figure 1.4: The Preference Browser.


1.2 The World menu

PIC Click again on the Pharo background.

You will see the World menu again. Most Pharo menus are not modal; you can leave them on the screen for as long as you wish by clicking the push pin icon in the top-right corner. Do this.

The world menu provides you a simple means to access many of the tools that Pharo offers.

PIC Have a closer look at the World and Tools menus. (Figure 1.3 (a))

You will see a list of several of the core tools in Pharo, including the browser and the workspace. We will encounter most of them in the coming chapters.

1.3 Sending messages

PIC Open a workspace. Type in the following text:

 
BouncingAtomsMorph new openInWorld  

PIC Now action-click. A menu should appear. Select do it (d) . (See Figure 1.5.)


PIC

Figure 1.5: “Doing” an expression


A window containing a large number of bouncing atoms should open in the top left of the Pharo image.

You have just evaluated your first Smalltalk expression! You just sent the message new to the BouncingAtomsMorph class, resulting in a new BouncingAtomsMorph instance, followed by the message openInWorld to this instance. The BouncingAtomsMorph class decided what to do with the new message, that is, it looked up its methods for handling new message and reacted appropriately. Similarly the BouncingAtomsMorph instance looked up its method for responding to openInWorld and took appropriate action.

If you talk to Smalltalkers for a while, you will quickly notice that they generally do not use expressions like “call an operation” or “invoke a method”, but instead they will say “send a message”. This reflects the idea that objects are responsible for their own actions. You never tell an object what to do — instead you politely ask it to do something by sending it a message. The object, not you, selects the appropriate method for responding to your message.

1.4 Saving, quitting and restarting a Pharo session

PIC Now click on the bouncing atoms window and drag it anywhere you like. You now have the demo “in hand”. Put it down by clicking anywhere.


PIC

Figure 1.6: A BouncingAtomsMorph.
PIC

Figure 1.7: The save as dialogue.


PIC Select World Save as , enter the name “myPharo”, and click on the OK button. Now select World Save and quit .

Now if you go to the location where the original image and changes files were, you will find two new files called “myPharo.image” and “myPharo.changes” that represent the working state of the Pharo image at the moment before you told Pharo to Save and quit . If you wish, you can move these two files anywhere that you like on your disk, but if you do so you may (depending on your operating system) need to also move, copy or link to the virtual machine and the sources file.

PIC Start up Pharo from the newly created “myPharo.image” file.

Now you should find yourself in precisely the state you were when you quit Pharo. The BouncingAtomsMorph is there again and the atoms continue to bounce from where they were when you quit.

When you start Pharo for the first time, the Pharo virtual machine loads the image file that you provide. This file contains a snapshot of a large number of objects, including a vast amount of pre-existing code and a large number of programming tools (all of which are objects). As you work with Pharo, you will send messages to these objects, you will create new objects, and some of these objects will die and their memory will be reclaimed (i.e., garbage-collected).

When you quit Pharo, you will normally save a snapshot that contains all of your objects. If you save normally, you will overwrite your old image file with the new snapshot. Alternatively, you may save the image under a new name, as we just did.

In addition to the .image file, there is also a .changes file. This file contains a log of all the changes to the source code that you have made using the standard tools. Most of the time you do not need to worry about this file at all. As we shall see, however, the .changes file can be very useful for recovering from errors, or replaying lost changes. More about this later!

The image that you have been working with is a descendant of the original Smalltalk-80 image created in the late 1970s. Some of these objects have been around for decades!

You might think that the image is the key mechanism for storing and managing software projects, but you would be wrong. As we shall see very soon, there are much better tools for managing code and sharing software developed by teams. Images are very useful, but you should learn to be very cavalier about creating and throwing away images, since tools like Monticello offer much better ways to manage versions and share code amongst developers.

PIC Using the mouse (and the appropriate modifier keys), meta-click on the BouncingAtomsMorph.5

You will see a collection of colored circles that are collectively called the BouncingAtomsMorph’s morphic halo. Each circle is called a handle. Click in the pink handle containing the cross; the BouncingAtomsMorph should go away.

1.5 Workspaces and Transcripts

PIC Close all open windows. Open a transcript and a workspace. (The transcript can be opened from the World Tools ... submenu.)

PIC Position and resize the transcript and workspace windows so that the workspace just overlaps the transcript.

You can resize windows either by dragging one of the corners, or by meta-clicking the window to bring up the morphic halo, and dragging the yellow (bottom right) handle.

At any time only one window is active; it is in front and has its border highlighted.

The transcript is an object that is often used for logging system messages. It is a kind of “system console”.

Workspaces are useful for typing snippets of Smalltalk code that you would like to experiment with. You can also use workspaces simply for typing arbitrarily text that you would like to remember, such as to-do lists or instructions for anyone who will use your image. Workspaces are often used to hold documentation about a captured image, as is the case with the standard image that we downloaded earlier (see Figure 1.2).

PIC Type the following text into the workspace:

 
Transcript show: hello world; cr.  

Try double-clicking in the workspace at various points in the text you have just typed. Notice how an entire word, entire string, or the whole text is selected, depending on whether you click within a word, at the end of the string, or at the end of the entire expression.

PIC Select the text you have typed and action-click. Select do it (d) .

Notice how the text “hello world” appears in the transcript window (Figure 1.8). Do it again. (The (d) in the menu item do it (d) tells you that the keyboard shortcut to do it is CMD–d. More on this in the next section!)


PIC

Figure 1.8: Overlapping windows. The workspace is active.


1.6 Keyboard shortcuts

If you want to evaluate an expression, you do not always have to action-click. Instead, you can use keyboard shortcuts. These are the parenthesized expressions in the menu. Depending on your platform, you may have to press one of the modifier keys (control, alt, command, or meta). (We will indicate these generically as CMDkey.)

PIC Evaluate the expression in the workspace again, but using the keyboard shortcut: CMD–d.

In addition to do it , you will have noticed print it , inspect it and explore it . Let’s have a quick look at each of these.

PIC Type the expression 3 + 4 into the workspace. Now do it with the keyboard shortcut.

Do not be surprised if you saw nothing happen! What you just did is send the message + with argument 4 to the number 3. Normally the result 7 will have been computed and returned to you, but since the workspace did not know what to do with this answer, it simply threw the answer away. If you want to see the result, you should print it instead. print it actually compiles the expression, executes it, sends the message printString to the result, and displays the resulting string.

PIC Select 3+4 and print it (CMD–p).

This time we see the result we expect (Figure 1.9).


PIC

Figure 1.9: “Print it” rather than “do it”.


 
3 + 4 -→ 7  

We use the notation -→ as a convention in this book to indicate that a particular Pharo expression yields a given result when you print it .

PIC Delete the highlighted text “7” (Pharo should have selected it for you, so you can just press the delete key). Select 3+4 again and this time inspect it (CMD–i).

Now you should see a new window, called an inspector, with the heading SmallInteger: 7 (Figure 1.10). The inspector is an extremely useful tool that will allow you to browse and interact with any object in the system. The title tells us that 7 is an instance of the class SmallInteger. The left panel allows us to browse the instance variables of an object, the values of which are shown in the right panel. The bottom panel can be used to write expressions to send messages to the object.


PIC

Figure 1.10: Inspecting an object.


PIC Type self squared in the bottom panel of the inspector on 7 and print it .

PIC Close the inspector. Type the expression Object in a workspace and this time explore it (CMD–I, uppercased i).

This time you should see a window labelled Object containing the text

root: Object . Click on the triangle to open it up (Figure 1.11).


PIC

Figure 1.11: Exploring Object.


The explorer is similar to the inspector, but it offers a tree view of a complex object. In this case the object we are looking at is the Object class. We can see directly all the information stored in this class, and we can easily navigate to all its parts.

1.7 The Class Browser

The class browser6 is one of the key tools used for programming. As we shall see, there are several interesting browsers available for Pharo, but this is the basic one you will find in any image.

PIC Open a browser by selecting World Class browser .7


PIC

Figure 1.12: The browser showing the printString method of class object.


We can see a browser in Figure 1.12. The title bar indicates that we are browsing the class Object.

When the browser first opens, all panes are empty but the leftmost one. This first pane lists all known packages, which contain groups of related classes.

PIC Click on the Kernel package.

This causes the second pane to show a list of all of the classes in the selected package.

PIC Select the class Object.

Now the remaining two panes will be filled with text. The third pane displays the protocols of the currently selected class. These are convenient groupings of related methods. If no protocol is selected you should see all methods in the fourth pane.

PIC Select the printing protocol.

You may have to scroll down to find it. Now you will see in the fourth pane only methods related to printing.

PIC Select the printString method.

Now we see in the bottom pane the source code of the printString method, shared by all objects in the system (except those that override it).

1.8 Finding classes

There are several ways to find a class in Pharo. The first, as we have just seen above, is to know (or guess) what category it is in, and to navigate to it using the browser.

A second way is to send the browse message to the class, asking it to open a browser on itself. Suppose we want to browse the class Boolean.

PIC Type Boolean browse into a workspace and do it .

A browser will open on the Boolean class (Figure 1.13). There is also a keyboard shortcut CMD–b (browse) that you can use in any tool where you find a class name; select the name and type CMD–b.

PIC Use the keyboard shortcut to browse the class Boolean.


PIC

Figure 1.13: The browser showing the definition of class Boolean.


Notice that when the Boolean class is selected but no protocol or method is selected, instead of the source code of a method, we see a class definition (Figure 1.13). This is nothing more than an ordinary Smalltalk message that is sent to the parent class, asking it to create a subclass. Here we see that the class Object is being asked to create a subclass named Boolean with no instance variables, class variables or “pool dictionaries”, and to put the class Boolean in the Kernel-Objects category. If you click on the ? at the bottom of the class pane, you can see the class comment in a dedicated pane (see Figure 1.14).


PIC

Figure 1.14: The class comment for Boolean.


Often, the fastest way to find a class is to search for it by name. For example, suppose that you are looking for some unknown class that represents dates and times.

PIC Put the mouse in the package pane of the browser and type CMD–f, or select find class …(f) by action-clicking. Type “time” in the dialog box and accept it.

You will be presented with a list of classes whose names contain “time” (see Figure 1.15). Choose one, say, Time, and the browser will show it, along with a class comment that suggests other classes that might be useful. If you want to browse one of the others, select its name (in any text pane), and type CMD–b.


PIC    PIC

Figure 1.15: Searching for a class by name.


Note that if you type the complete (and correctly capitalized) name of a class in the find dialog, the browser will go directly to that class without showing you the list of options.

1.9 Finding methods

Sometimes you can guess the name of a method, or at least part of the name of a method, more easily than the name of a class. For example, if you are interested in the current time, you might expect that there would be a method called “now”, or containing “now” as a substring. But where might it be? The method finder can help you.

PIC Select World Tools ... Method finder . Type “now” in the top left pane, and accept it (or just press the RETURN key).

The method finder will display a list of all the method names that contain the substring “now”. To scroll to now itself, move the cursor to the list and type “n”; this trick works in all scrolling windows. Select “now” and the right-hand pane shows you the classes that define a method with this name, as shown in Figure 1.16. Selecting any one of them will open a browser on it.


PIC

Figure 1.16: The method finder showing all classes defining a method named now.


At other times you may have a good idea that a method exists, but will have no idea what it might be called. The method finder can still help! For example, suppose that you would like to find a method that turns a string into upper case, for example, it would translate eureka into EUREKA.

PIC Type eureka . EUREKA into the method finder and press the RETURN key, as shown in Figure 1.17.

The method finder will suggest a method that does what you want.8

An asterisk at the beginning of a line in the right pane of the method finder indicates that this method is the one that was actually used to obtain the requested result. So, the asterisk in front of String asUppercase lets us know that the method asUppercase defined on the class String was executed and returned the result we wanted. The methods that do not have an asterisk are just the other methods that have the same name as the ones that returned the expected result. So CharacterasUppercase was not executed on our example, because eureka is not a Character object.


PIC

Figure 1.17: Finding a method by example.


You can also use the method finder for methods with arguments; for example, if you are looking for a method that will find the greatest common factor of two integers, you might try 25. 35. 5 as an example. You can also give the method finder multiple examples to narrow the search space; the help text in the bottom pane explains how.

1.10 Defining a new method

The advent of Test Driven Development9 (TDD) has changed the way that we write code. The idea behind TDD is that we write a test that defines the desired behaviour of our code before we write the code itself. Only then do we write the code that satisfies the test.

Suppose that our assignment is to write a method that “says something loudly and with emphasis”. What exactly could that mean? What would be a good name for such a method? How can we make sure that programmers who may have to maintain our method in the future have an unambiguous description of what it should do? We can answer all of these questions by giving an example:

When we send the message shout to the string “Don’t panic” the result should be “DON’T PANIC!”.

To make this example into something that the system can use, we turn it into a test method:

Method 1.1: A test for a shout method
 
testShout 
    self assert: (Dont panic shout = DONT PANIC!)  

How do we create a new method in Pharo? First, we have to decide which class the method should belong to. In this case, the shout method that we are testing will go in class String, so the corresponding test will, by convention, go in a class called StringTest.


PIC

Figure 1.18: The new method template in class StringTest.


PIC Open a browser on the class StringTest, and select an appropriate protocol for our method, in this case tests - converting , as shown in Figure 1.18. The highlighted text in the bottom pane is a template that reminds you what a Smalltalk method looks like. Delete this and enter the code from method 1.1.

Once you have typed the text into the browser, notice that the bottom pane is outlined in red. This is a reminder that the pane contains unsaved changes. So select accept (s) by action-clicking in the bottom pane, or just type CMD–s, to compile and save your method.

If this is the first time you have accepted any code in your image, you will likely be prompted to enter your name. Since many people have contributed code to the image, it is important to keep track of everyone who creates or modifies methods. Simply enter your first and last names, without any spaces, or separated by a dot.

Because there is as yet no method called shout, the browser will ask you to confirm that this is the name that you really want — and it will suggest some other names that you might have intended (Figure 1.20). This can be quite useful if you have merely made a typing mistake, but in this case, we really do mean shout, since that is the method we are about to create, so we have to confirm this by selecting the first option from the menu of choices, as shown in Figure 1.20.


PIC

Figure 1.19: Entering your name.



PIC

Figure 1.20: Accepting the StringTest method testShout.


PIC Run your newly created test: open the SUnit TestRunner from the World menu.

The leftmost two panes are a bit like the top panes in the browser. The left pane contains a list of categories, but it’s restricted to those categories that contain test classes.

PIC Select CollectionsTests-Text and the pane to the right will show all of the test classes in that category, which includes the class StringTest. The names of the classes are already selected, so click Run Selected to run all these tests.


PIC

Figure 1.21: Running the String tests.


You should see a message like that shown in Figure 1.21, which indicates that there was an error in running the tests. The list of tests that gave rise to errors is shown in the bottom right pane; as you can see, StringTest#testShout is the culprit. (Note that StringTest#testShout is the Smalltalk convention to identify the testShout method of the StringTest class.) If you click on that line of text, the erroneous test will run again, this time in such a way that you see the error happen: “MessageNotUnderstood: ByteStringshout”.

The window that opens with the error message is the Smalltalk debugger (see Figure 1.22). We will look at the debugger and how to use it in Chapter 6.


PIC

Figure 1.22: The (pre-)debugger.


The error is, of course, exactly what we expected: running the test generates an error because we haven’t yet written a method that tells strings how to shout. Nevertheless, it’s good practice to make sure that the test fails because this confirms that we have set up the testing machinery correctly and that the new test is actually being run. Once you have seen the error, you can Abandon the running test, which will close the debugger window. Note that often with Smalltalk you can define the missing method using the Create button, edit the newly-created method in the debugger, and then Proceed with the test.

Now let’s define the method that will make the test succeed!

PIC Select class String in the browser, select the converting protocol, type the text in method 1.2 over the method creation template, and accept it. (Note: to get a

Select Wa71er the m. 663-->

The error is, of course,>"lstinline"fig3xs="phvr8t-xi8t-2C6; " ex4ht:labircA test for aTi8t-">fro1 -->

 
<672an>testShout 
<-x-85"> 
  self assert:Wa71er the mpan>  ((<><674s="phvr8t-x-x-85"> PANIC!<> 
How do we create a new method in Pharo? First, we have to decide 32ich class the method should b6 Tut shomalook at ss="noi asUppercase
lets us know that the methStrinwill lsee,hvr8t-xn claan>Wa71eplri8t-" practass="-85">Abandclaall-i class="follf: feen0A0;Meine">String
ssage> nderstooy -->, whichri8t-">1.2 3 ="dx8-20011">StrinasUppercase lets us know that the meth


The error is, of course, exactly 9" >

The advent of in the brow 10ention, golass="f suomaryte-mark">mass="f r cointroduced ntendespan ass="-envirould be" id=classhich ke su havem -->san> rrors s how.e to t id= closnt" tof >Atinline">ass="-/> sx4ht:ref: class="had2"><7;y -omethilacteaction, as sto k./span>ass="- look e thagted ndes swithm :ger --1900n, rcl-an> ll-caps">MM Y220;omethilaunpanvari"phvraoll span>A"tlass="lmsharo.png" alt=with line- e clascode fo"phvr8telesine">sniphv Y220;div cl"bugger (see Fi1p> ).span>fo"p,t


&p="nt cioindent" > &insit becioindent" >  <"> (tlass="lmsharo.png to compile and save your method. up cltlass="lmsharo.png" alt= you mig- e clascod id by n>fo"p hvr8tvr8/span>d8-2000 x8-onup cltlass="lmsharo.png" alt= lasssrrors g- e clascod an>fo"p hvr8t unioi">


The error is, of course, lass="col4have !--tex4ht:labrossppekt-x- the name of a cla>[div class="figur3" > assnan>> assprev> #panl"figur1" > assprev-panl> a> cla> assup> a>lass=, of course, la > >