Smalltalk Cheat Sheet
Foundational Smalltalk syntax covering message sends, class definitions, block-based conditionals and loops, and common collection operations.
Basic Syntax & Messages
Variables and the three kinds of message sends.
"Comments are written in double quotes"| x y |x := 5.y := 10.Transcript showCr: 'Hello, World!'.3 factorial. "unary message"3 + 4. "binary message"3 max: 4. "keyword message"(3 + 4) * 2. "parentheses control evaluation order"
Class Definition
Defining a class and adding methods.
Object subclass: #Animal instanceVariableNames: 'name sound' classVariableNames: '' package: 'MyApp'.Animal >> makeSound Transcript showCr: name, ' says ', sound.Animal >> name: aName sound: aSound name := aName. sound := aSound.
Conditionals & Loops (Blocks)
Control flow is implemented as messages that take blocks.
(x > 0) ifTrue: [Transcript showCr: 'positive'] ifFalse: [Transcript showCr: 'not positive'].1 to: 5 do: [:i | Transcript showCr: i printString].[x < 10] whileTrue: [x := x + 1].
Collections
Working with OrderedCollection and blocks-as-callbacks.
| coll |coll := OrderedCollection new.coll add: 1; add: 2; add: 3.coll do: [:each | Transcript showCr: each printString].(coll collect: [:each | each * each]) printNl.(coll select: [:each | each > 1]) printNl.
Cascades & yourself
Send multiple messages to the same receiver with semicolons, and return the receiver instead of the last reply with yourself.
| coll |coll := OrderedCollection new.coll add: 1; add: 2; add: 3; yourself."Without yourself, the cascade would evaluate to the result of thelast message (add: 3 returns 3, not the collection)."coll := (OrderedCollection new) add: 'a'; add: 'b'; yourself.Transcript show: 'a='; show: 1 printString; show: ' b='; showCr: 2 printString.
Exception Handling
Signal, catch, resume, and retry exceptions with on:do: and ensure:.
[ 1/0 ] on: ZeroDivide do: [:e | Transcript showCr: 'caught: ', e messageText].[ self error: 'bad input' ] on: Error do: [:e | e return: nil]."ensure: runs regardless of whether an exception was raised"[ self riskyOperation ] ensure: [ stream close ]."retry re-executes the protected block from the top"| attempts |attempts := 0.[ attempts := attempts + 1. self connect ] on: NetworkError do: [:e | attempts < 3 ifTrue: [e retry] ifFalse: [e pass]].
Class Extension & Metaclasses
Reopen existing classes to add methods, and understand class-side (metaclass) methods.
"Reopening a built-in class to add behavior"Integer extend [ isPrime (self < 2) ifTrue: [^false]. 2 to: self sqrtFloor do: [:i | (self \\ i = 0) ifTrue: [^false]]. ^true]"Class-side methods live on the metaclass, e.g. class-side new"Object subclass: #Point instanceVariableNames: 'x y' classVariableNames: '' package: 'MyApp'.Point class >> x: ax y: ay | p | p := self new. p setX: ax y: ay. ^p
Blocks as Closures & Non-Local Returns
Blocks close over enclosing variables and ^ inside a block returns from the enclosing method, not the block.
makeCounter | count | count := 0. ^[ count := count + 1. count ]"counter := self makeCounter. counter value. counter value. -> 1, 2"findFirstEven: aCollection aCollection do: [:each | (each even) ifTrue: [^each]]. "non-local return exits findFirstEven:" ^nil"numArgs must match: value, value:, value:value:, value:value:value:"adder := [:a :b | a + b].(adder value: 3 value: 4) printNl.
Reflection & Introspection
Core messages for inspecting objects and classes at runtime.
- anObject class- returns the object's class
- aClass superclass- returns the parent class in the hierarchy
- anObject respondsTo: #foo- true if the object understands the message #foo
- anObject isKindOf: aClass- true if anObject is aClass or a subclass instance
- anObject perform: #foo with: arg- sends a message dynamically by selector symbol
- aClass selectors- set of message selectors implemented by the class
- anObject inspect- opens an interactive inspector on the object
- Smalltalk at: #Foo put: obj- registers a global variable in the system dictionary
Everything in Smalltalk, including True, False, and even classes themselves, is an object that responds to messages — there are no special-cased keywords, so `ifTrue:ifFalse:` is just an ordinary message sent to a Boolean.