How does Smalltalk look like?

Tagged:

Let's define a class called Person, holding a name and an age. (Note: this code only works in Smalltalk 2.95a and later. The syntax for previous versions is more verbose and less clear).

Object subclass: Person [
    | name age |
    Person class >> name: aString age: anInteger [
        ^self new name: aString; age: anInteger; yourself
    ]

    name [ ^name ]
    name: aString [ name := aString ]
    age [ ^age ]
    age: anInteger [ age := anInteger ]

    printOn: aStream [
        aStream << ('%1 (%2)' % {name. age})
    ]
]

Now, let's try it out:

(Person name: 'Paolo' age: 27)    "returns Paolo (27)"

Let's add two of them into a collection:

coll := {
   Person name: 'Paolo' age: 27.
   Person name: 'Luisa' age: 28.
}

... so that we can sort them:

coll asSortedCollection: [ :x :y | x name <= y name ]
coll asSortedCollection: [ :x :y | x age <= y age ]

We can also load people from a file. This uses a powerful tool for iteration known as the stream:

file := (File name: 'foo') readStream.

The following lines modify the stream in place. That is, each line returns another stream:

lines := file lines.
lines := lines select: [ :line | line ~ '^[A-Za-z]+ [0-9]+$' ].
fields := lines collect: [ :line | line subStrings ].
people := fields collect: [ :data |
            Person name: data first age: data second asInteger ].

These lines operate on different kinds of stream: one that returns lines, one that filters away invalid data, one that processes what remains, and one that finally creates Person objects. However, all of them operate in the same way.

Also note that so far the code has not read a single line from the file! This allows big amounts of data to be processed efficiently. Continuing the example, the following iteration command prints the people in the file, keeping in memory only one line at a time:

people do: [ :each | each printNl ]

That's it!

User login