Classes & Instances
In the System Browser, select a package, and the code pane shows a class template.
13.1 Defining a class (Pharo fluid syntax)
In the System Browser, select a package, and the code pane shows a class template. Edit it and accept (Ctrl+S):
Object << #BankAccount — superclass << class name.
slots: — instance variables (Pharo calls them slots; they are first-class objects).
tag: — an optional sub-grouping inside the package (shown as a folder in the browser).
package: — the package that owns the class.
Other optional keywords: sharedVariables: (class variables), sharedPools:, traits:, layout: (e.g., VariableLayout, ByteLayout), and comment: is set separately via the comment pane.
When you evaluate a fluid definition from a Playground rather than accepting it in the browser, send install to the builder to actually create the class:
Object << #BankAccount
slots: { #owner . #balance };
tag: 'Model';
package: 'Bank-Core'(Object << #BankAccount
slots: { #owner . #balance };
package: 'Bank-Core') install.13.2 Older (classic) syntax
Pharo 11 and earlier — and Squeak, Cuis, VisualWorks, VA Smalltalk, GemStone — use a keyword message to the superclass:
Pharo still understands the classic message, so old scripts keep working. GNU Smalltalk uses a bracket syntax (Chapter 41).
"Pharo ≤ 11"
Object subclass: #BankAccount
instanceVariableNames: 'owner balance'
classVariableNames: ''
package: 'Bank-Core'
"Squeak / Cuis / classic Smalltalk-80"
Object subclass: #BankAccount
instanceVariableNames: 'owner balance'
classVariableNames: ''
poolDictionaries: ''
category: 'Bank-Core'13.3 Writing methods
In the browser, select the class, a protocol (e.g., *accessing*), and type a method in the code pane; accept with Ctrl+S. In text, methods are shown as ClassName >> selector:
The first line is the message pattern (selector and argument names).
A method without an explicit ^ returns self.
Instance variables are visible only inside the object's methods — encapsulation is total: other objects must send messages.
BankAccount >> initialize
super initialize.
balance := 0
BankAccount >> owner
^ owner
BankAccount >> owner: aString
owner := aString
BankAccount >> balance
^ balance
BankAccount >> deposit: anAmount
anAmount <= 0 ifTrue: [ ^ self error: 'Deposit must be positive' ].
balance := balance + anAmount
BankAccount >> withdraw: anAmount
anAmount > balance ifTrue: [ ^ self error: 'Insufficient funds' ].
balance := balance - anAmount13.4 Creating instances
In VisualWorks and some older dialects new does not call initialize; write a class-side new ^ super new initialize there.
| acct |
acct := BankAccount new. "new allocates, then sends #initialize (Pharo, Squeak, Cuis, GNU 3.2+)"
acct owner: 'Ada'.
acct deposit: 100; withdraw: 30.
acct balance. "→ 70"13.5 Class-side instance creation methods
Toggle to the class side in the browser and add constructors:
Use self new, not BankAccount new, so subclasses get instances of themselves.
BankAccount class >> owner: aString
^ self new
owner: aString;
yourself
BankAccount class >> owner: aString balance: anAmount
^ (self owner: aString) deposit: anAmount; yourself(BankAccount owner: 'Grace' balance: 500) balance. "→ 500"13.6 Printing objects
Override printOn: to control how an object is displayed in inspectors, debuggers, and Print it:
printString calls printOn:; displayString (for end users) calls displayStringOn:; storeString produces source that rebuilds the object.
BankAccount >> printOn: aStream
super printOn: aStream. "→ 'a BankAccount'"
aStream
nextPutAll: '(';
nextPutAll: owner asString;
nextPutAll: ': ';
print: balance;
nextPutAll: ')'(BankAccount owner: 'Ada' balance: 70) printString. "→ 'a BankAccount(Ada: 70)'"13.7 Equality and hashing
If you override =, you must override hash consistently, or Sets and Dictionaries will misbehave:
Object << #Money
slots: { #amount . #currency };
package: 'Bank-Core'
Money >> = other
self == other ifTrue: [ ^ true ].
self class = other class ifFalse: [ ^ false ].
^ amount = other amount and: [ currency = other currency ]
Money >> hash
^ amount hash bitXor: currency hash13.8 Class comments
Every class has a comment (the *Comment* tab). Pharo's convention is CRC style: *I represent… My responsibility is… I collaborate with…*, followed by examples. Missing comments are flagged by the Quality Assistant.