Instance, Class & Class-Side Variables
Classic syntax for the class-side instance variable:
15.1 Three kinds of class-related state
Classic syntax for the class-side instance variable:
nobody — each instance has its own the class, all subclasses, all their instances both instance and class side Class-side instance variable nobody — Vehicle and each subclass have separate values
Object << #Vehicle
slots: { #plate }; "instance variables: one per instance"
sharedVariables: { #Registry }; "class variable: ONE shared by Vehicle, subclasses, and all instances"
package: 'Fleet'
Vehicle class << Vehicle class
slots: { #count } "class-side instance variable: one per class object"Vehicle class instanceVariableNames: 'count'15.2 Class variables
Class variables are capitalized by convention. They are a form of global scoped to a hierarchy — use them for constants and caches shared across the hierarchy.
Vehicle class >> registry
^ Registry ifNil: [ Registry := OrderedCollection new ]
Vehicle >> register
self class registry add: self15.3 Class-side instance variables: per-class counters
With a class variable instead, all three would share one counter.
Vehicle class >> new
count := (count ifNil: [ 0 ]) + 1.
^ super new
Vehicle class >> count
^ count ifNil: [ 0 ]
Vehicle << #Car slots: { #seats }; package: 'Fleet'.
Vehicle << #Truck slots: { #payload }; package: 'Fleet'.Car new. Car new. Truck new.
Car count. "→ 2"
Truck count. "→ 1 — each class keeps its own 'count'"15.4 Singleton with a class-side instance variable
Object << #AppConfiguration slots: { #settings }; package: 'App'.
AppConfiguration class << AppConfiguration class slots: { #uniqueInstance }.
AppConfiguration class >> uniqueInstance
^ uniqueInstance ifNil: [ uniqueInstance := self new ]
AppConfiguration class >> reset
uniqueInstance := nil15.5 Class initialization
A class-side initialize method runs once, when the class is loaded (not when instances are created). Re-run it manually after changing it:
Vehicle class >> initialize
Registry := OrderedCollection new
Vehicle initialize. "run it manually during development"15.6 Lazy initialization
Vehicle >> plate
^ plate ifNil: [ plate := 'UNREGISTERED' ]15.7 Slots are objects
Pharo's slots are first-class: Vehicle slots, (Vehicle slotNamed: #plate) read: aVehicle. Custom slot classes enable special behaviors (e.g., WeakSlot, PropertySlot, observable slots): slots: { #items => WeakSlot }.