September 29, 2022

The Protocol of Set


For the purposes of this discussion I will assume that the collection of artists' names is to be held in a set. The "stable" of artists represented by the gallery is unlikely to exceed more than a few dozen and although the duplication of names could happen, it is a requirement that this system, ensures that each artist's name is unique. The two Richards will be recorded as 'Richard A. Smith' and 'Richard P. Smith'. Artists will leave/die/be expelled/be taken on etc., therefore the Set class seems, at this stage, a good choice for recording names. However, as always,, things may change.

Message selectors for collection classes fall into six general categories.

The abstract class Collection includes a number of instance message selectors that are inherited by all its subclasses. However, there are two message selectors that Collection inherits from Object. These are at: and at:put:
It should be obvious that these are only applicable to indexable collections. A set has no order, or sequence, for holding its elements and consequently Set overrides these two selectors by implementing an error notification.

We can now look at some selectors of Set.

accessing size
adding add:
removing remove: , remove:ifAbsent:
testing includes: , isEmpty
enumerating do:
converting asBag , asArray , asOrderedCollection (etc inherited from Collection)

Cordelia Pleydell-Bouverie, the owner of The Quad Gallery, has amassed a collection of paintings, drawings, prints and sculpture over the years. She decides that it's time to off-load some of these to pay for the new thatched roof on her Tudor mansion, which is set in five acres of prime Suffolk real estate. The gallery, in other words Cordelia, has decided to put together a small show of works by artists who have gone to the great studio/pub in the sky. A set called setOfDeadArtists is created and holds a collection of strings representing the names of all the artists.

setOfDeadArtists := Set new.
setOfDeadArtists add: 'Francis Bacon';
                 add: 'Peter Hobbs';
                 add: 'Duncan Grant';
                 add: 'Prunella Clough';
                 add: 'Mario Dubsky';
                 add: 'Harry Thubron';
                 add: 'Victor Vaserely';
                 add: 'Roger Hilton';
                 add: 'Henry Moore';
                 add: 'Barbara Hepworth';
                 add: 'Jacob Epstein'

The textual representation of this set is:

Set ('Mario Dubsky' 'Prunella Clough' 'Harry Thubron' 'Jacob Epstein' 'Henry Moore' 'Duncan Grant' 'Victor Vaserely' 'Roger Hilton' 'Peter Hobbs' 'Francis Bacon' 'Barbara Hepworth')

Since a set is unordered, the order that these strings are given is entirely arbitrary.

Most exhibitions require considerable planning and Cordelia's is no exception. However she discovers shortly before the show that Henry Moore's linocut, 'Reclining Nude with Gas-mask', inherited from the divorce deal with her first husband, is a fake. Fear not, she will off-load this at auction at some later date, but for now Henry Moore's single contribution must go and consequently setOfDeadArtists needs some adjustment. No problem.

setOfDeadArtists remove: 'Henry Moore'

'Henry Moore' is returned as the message answer and this element is removed from the set. However if a typo error had resulted in the evaluation of

setOfDeadArtists remove: 'Henry moore'

a system error would notify the user that the element was not found. When removing an element from a set there is a safer alternative.

setOfDeadArtists remove: 'Henry Moore' ifAbsent: [Dialog warn: 'This name is not present']

This ensures that if the element is absent the code in the block is executed.

An alternative is to check for inclusion first with the includes: message, the argument being the element that you are checking for. true or false are returned and one of these Boolean objects can receive an ifTrue:ifFalse: message. For example:

(setOfDeadArtists includes: 'Henry Moore')
   ifTrue: [setOfDeadArtists remove: 'Henry Moore']
   ifFalse: [Dialog warn: 'This name is not present']

size simply returns the number of elements in the collection object. Thus

setOfDeadArtists size

returns 10

isEmpty answers with a Boolean object to indicate the presence of at least one element, or none

setOfDeadArtists isEmpty

which in this case returns false

The one other message that I want to discuss is the generalised iterator do:
This takes as the argument a block which declares a single block argument. The general form is

aSet do: [:each | each doSomething]

where each, we can choose any word we like here, is the block argument. The do: method iterates over each element of the set and repeatedly sends the value: message to the block with the current element as the argument to value:
To illustrate this consider the following:

setOfDeadArtists do: [: each | Dialog warn: 'Artist''s name: ', each ]

If this is evaluated we get a series of dialogue boxes listing each artist in the set. Each element of the set is supplied as the argument to value: ; each is simply a reference to the argument of value:
Here is one of the ten value: messages that are sent to the block

[: each | Dialog warn: 'Artist''s name: ', each]value: 'Mario Dubsky'

which produces this

Dialogue box with output - Artist's name: Mario Dubsky


Other examples of iteration will be discussed later. Meanwhile take a look at a subclass of Set, the Dictionary class.

Next page » Dictionary

Previous page « Set
































































Up to top of page