A gentle introduction to classes and methods in Smalltalk


This tutorial illustrates how to turn the Jumble puzzle snippet into a class with methods.

You should have already read A gentle introduction to Pharo Smalltalk.


We have seen how to write a snippet that unscrambles a string of characters into a valid English word using an unscrambling dictionary. Now let's see how to turn this code into a class that encapsulates the dictionary and provides an unscrambling method.

The key thing to understand is that programming in Smalltalk consists in making incremental changes to the running system. Each individual change either defines or redefines a class or a method. Each source code change will be logged in the changes file (see Pharo architecture).

Creating a new class

Normally you will create new classes either in the Coder or directly in a Playground Pharo snippet. For example, assuming the Jumble class does not already exist, the code snippet below will show the name of the class in red, next to a little “quick fix” wrench icon that will allow us to directly create the class. We won't do this, however.

"We can't run this snippet because the class Jumble doesn't exist yet (shown in red). We could 'fix it' by clicking the wrench icon, but instead we will load in the changes from the next snippet below."

Jumble new

Instead we will implement our changes directly within the tutorial.

Everything happens by sending messages, and it is the same for creating new classes. We send the message #subclass:... to the the superclass of the class we want to create. In this case, we ask Object ProtoObject subclass: #Object instanceVariableNames: '' classVariableNames: 'DependentsFields' package: 'Kernel-Objects' to create Jumble as a subclass.

Click on the checkmark to accept this change:

Object subclass: #Jumble
	instanceVariableNames: 'wordDict'
	classVariableNames: ''
	package: 'Tutorial-Jumble'.

Jumble class
	instanceVariableNames: ''

Class comments

It is good practice to always provide a class comment describing the intent and usage of the class, and possibly other details. Let's add a comment:

A Jumble is an object that knows how to unscramble English words:

	Jumble new unJumble: 'gameses'

It encapsulates a dictionary of lists of words, keyed by a sorted string of characters in each word. It unjumbles a word by sorting its characters to form a key and looking up the key in the dictionary.


We can create a new Jumble by sending it the unary message new. If we do this and inspect it, we will see in the raw view that its wordDict is unitialized:

Jumble new

To automatically initialize a new instance of a class, we can implement the initialize method. The #initialize message will be sent as soon as it is created.

We already have the code from our earlier snippet exercise; we just have to turn it into a method:

"protocol: #accessing"

Jumble >> initialize

	| wordlistUrl words wordList |
	wordlistUrl := 'https://raw.githubusercontent.com/dwyl/english-words/master/words_alpha.txt'.
	words := (ZnUrl fromString: wordlistUrl) retrieveContents.
	wordList := Character cr asString , Character lf asString split:
	wordDict := Dictionary new.
	wordList do: [ :word | 
		| key |
		key := word sorted.
			at: key
			ifPresent: [ :v | v addLast: word ]
			ifAbsentPut: [ { word } asOrderedCollection ] ]


Accept the changes and then you should be able to see the method we have created:


Notice that the only changes to the original snippet are:

1. We added a method declaration in the first line (initialize).

2. We declared the local variables wordlistUrl etc. within or-bars (|...|).

3. We declared key as variable local to its block (|key|).


Now we just have to add the unjumble method:

"protocol: #accessing"

Jumble >> unJumble: aString

	^ wordDict at: aString sorted

Now we have our first working version:

Jumble new unJumble: 'gameses'

Next: test examples and code cleaning

This first version seems to work, but we have no tests, the Jumble fails with an exception if the word cannot be unjumbled, and the source file is hard-wired. To see how we can fix this, continue with: Introducing test examples and code cleaning

Links to Pages containing missing references - allowed failures to allow references to missing classes and methods in the page.