Welcome to my full Squeak tutorial. Here you will learn about Squeak, how to program in Squeak Smalltalk, how to use the Scratch Source, and much more!
Tutorials
Tutorials start with a Bolded Title and are located inside the proceeding
Quote box.
Most tutorials will have step-by-step instructions. Next to these instructions will be one or more links like this: (◊). Click one of these links to see the result(s) of the step in an image (screenshot).
Getting Squeak
You can skip this step if you either:
A) Have already downloaded (and installed) Squeak
B) Want to use the Scratch Source Code (download)(◊) You can download Squeak from the Squeak website (http://www.squeak.org/). Once you arrive there, select the download link appropriate for your system from the right-aligned box labeled "Downloads."
Files Only Version: If you have restrictions on the content you can install on your computer, you can also download the files-only version, located on the Download Page. If you do this, you can skip the rest of the tutorial
(◊) Go ahead and run the installer. Click the "Next" button to proceed.
(◊) Read and agree to the terms of service by clicking the "I Agree" button.
(◊) Select the components you want to install (optional) and click the "Next" button to proceed.
(◊) Select an installation folder and click "Install" button to install Squeak.
(◊) Allow Squeak to fully install, then click the "Next" button to continue.
(◊) Click the "Finish" button to finish the installation and start Squeak (optional).
Getting Started
(◊) Open Squeak by running the application or (files-only version) dragging the image file ("Squeak***********.image" or "ScratchSourceCode1.4.image") onto the VM ("Squeak.exe" or your Scratch VM)
(◊) Click the "blank space" (called the World) to bring up the World Menu. Select "projects..."
(◊) (◊) Select "create new morphic project" from the subsequent menu.
(◊) Hold the "Shift" key while clicking on the text "Unnamed1" (the project title).
(◊) (◊) Rename your project (I called it "My First Project") and press the "Enter" key to exit the title editor
(◊) Click on the project thumbnail to jump to it (you should see an animation of the project growing to fill the screen).
(◊) Open the World Menu again by clicking the "blank space." This time, select "open..."
(◊) » Select "workspace" from the subsequent menu.
(◊) Copy-and-paste (Windows Alt+C, Mac Command+C) the following text into the workspace. Don't worry about what it says/does, we'll talk about it later.| menu specs choice morph rect |
menu := CustomMenu new.
specs := #(foo bar baz - other).
specs do: [:s |
s = #-
ifTrue: [
menu addLine]
ifFalse: [
menu add: s asString action: s asString asSymbol]].
choice := menu startUp.
morph := StringMorph new contents: choice asString; font: (StrikeFont familyName: 'Helvetica' pointSize: 24).
rect := (0@0 extent: 1@1) newRectFrom: [:r |
Sensor cursorPoint extent: morph extent].
morph position: rect topLeft.
[Sensor anyButtonPressed] whileTrue: [
World displayWorldSafely].
World addMorphFront: morph.(◊) Highlight all the text by clicking and dragging or by pressing (Windows) Alt+C or (Mac) Command+C. Right-click (Mac option-click) the selection and select "do it (d)" from the menu.
(◊) A menu should pop up. Make your selection (it doesn't matter, this is just a demo).
(◊) Now you should see a small outline of a rectangle which follows you mouse. Click in the desired region.
(◊) A new StringMorph is added to the World. You can repeat this process (Highlight, do it, select, place) as many times as you want, or play around with the StringMorphs themselves. Try clicking and dragging or Alt+Clicking them and selecting something from the pop-up "halo."
(◊) Example: I've selected "change color" (the eyedropper icon) from the halo and changed the color of the StringMorph
Our First Squeak Code - How Does it Work?
Let's look at the example code line-by-line.
Code:
1 : | menu specs choice morph rect |This line declares "temporary variables," that is, variables which are only used in this code, nowhere else. These variables are declared: menu, specs, choice, morph, rect. Variables are pieces of data which have a value which can change.
Code:
2 : menu := CustomMenu new.This assigns something to the variable "menu" by using the := operator. This means that it changes the value of the variable "menu". Here's what it's assigning to that variable: a new instance (new) of the class CustomMenu. It fetches this new instance by sending the "message" new to the class CustomMenu. Classes and methods are described briefly after this.
Code:
3 : specs := #(foo bar baz - other).This is also an assignment. It is assigning an Array (called a list in Scratch) of Symbols to "specs." We don't need to worry about exactly what a symbol is yet. It is similar to a String, which is a sequence of characters (letters, numbers, etc.).
Code:
4 : specs do: [:s |This is sending the message "do:" to the variable specs. What it does is loop through the "block" (think BYOB lambdas) given as the first argument (a value sent with the message). For every item of the array/list, it evaluates the block.
Code:
5-9 : s = #- ifTrue: [ menu addLine] ifFalse: [ menu add: s asString action: s asString asSymbol]].
This is a Squeak if statement, in the form of a message sent to a Boolean (true or false) value. It tests if the Symbol given is equal to "-". If it is, it just adds a line to the menu. If it isn't, it just adds the Symbol itself to the menu with an action of the same thing. The "asString" and "asSymbol" convert the variable "s" to the correct type.Code:
10 : choice := menu startUp.This line starts the menu up (displays it and waits for the user to select an option) and then stores the user's choice in the variable "choice."
Code:
11 : morph := StringMorph new contents: choice asString; font: (StrikeFont familyName: 'Helvetica' pointSize: 24).This line creates a new StringMorph, a Morph (graphical display object) which contains text in a certain font. It first sets the contents (the text in the StringMorph), then the font.
Code:
12-13 : rect := (0@0 extent: 1@1) newRectFrom: [:r | Sensor cursorPoint extent: morph extent].These lines create a new rectangle (defined by the top-left corner and the height and width as a point) and sends it the message newRectFrom: with a block as an argument. newRectFrom: evaluates a block and shows the user a preview of the rectangle returned by the block until the user either presses or releases a mouse button. This particular block makes a rectangle with the width and height of the StringMorph which has its top-left corner at the mouse.
Code:
14 : morph position: rect topLeft.This line sets the position of the StringMorph to the top-left corner of the Rectangle chosen by the user in the above lines.
Code:
15-16 : [Sensor anyButtonPressed] whileTrue: [ World displayWorldSafely].These lines keep displaying the Squeak World until the user releases the mouse button.
Code:
17 : World addMorphFront: morph.This line adds the StringMorph we've created and positioned to the Squeak World.
Smalltalk - the Basics
In this tutorial you will learn about the basics of Smalltalk code and syntax. Let's start off with classes, the things that contain all of Squeak's code.
Note: this tutorial is also located in the "Smalltalk Basics" project in the tutorial image.
Classes
Classes are basically blueprints for creating instances, objects which have a class as their data type. A new instance is created through sending the new message to a class, or some other instance creation method (like basicNew, newFrom:, etc.). Each instance of a class has its own variables and methods (functions), called instance variables and instance methods. Classes can also have their own variables and methods, called static variables or class variables and static methods or class methods. Classes are referenced throught global variables of the same name, such as Color or DisplayObject. Here is an example of creating a new instance of a class:Color new
Pretty easy, right?
Messages
Messages are simply functions implemented in a class. They can include the keyword "self," which references the receiver of (thing being affected by) the message. For example:Color new alpha: 0.4
sends the "alpha:" message to an instance of the class "Color" (the receiver). Also fairly straightforward.
Now for some syntax!• Every line ends with a . (period/dot character). For example:
Color new.
• Comments look like this:
"Stuff in a comment" Stuff outside a comment "Multi
Line
Comment"• Sending messages: use the : (colon character) to send arguments. Arguments are values sent with the message that the method can then use in its code. For example:
Color new alpha: 0.5
• Numbers look just like they do in English:
Color new alpha: 0.5
• Strings start and end with a ' (single-quote/apostrophe character). For example:
StringMorph new contents: 'Hello, World'
You now have a pretty good understanding of Smalltalk code, but there's one more feature that you can do so much with, even if it's a bit harder to wrap your head around.
Blocks
Here's where things get a little tricky. Blocks are basically blocks (hence the name) of un-evaluated code, like BYOB lambdas. They can take arguments (just like methods/messages) and can return a value (just like messages). Here is their syntax:[:t1 :t2 :t3 | "Code goes here" Color new. Color new alpha: 0.5. "The value of the last line is returned to the sender:" StringMorph new contents: 'Hello, World']
"What is this?" you might ask. Here is the answer: a block is like a little piece of code waiting to be evaluated. It's like knowing how to make a sandwich rather than actually making the sandwich. Some (but not all!) blocks take arguments; this is like knowing how to make a sandwich with ingredients given to you.
"How would I use this?" you might ask. Well, here are some common uses:• Making a "function" without defining a new method, i.e.:
| addTwo |
addTwo := [:num | num + 2].
Transcript show: (addTwo value: 2) asString. "=> 4"
Transcript show: (addTwo value: -10) asString. "=> -8"
Transcript show: (addTwo value: (10 * 2 + 3.14159 * 2.541) rounded - 0.0528) asString. "=> 60.9472"• Control structures (if, repeat, while, etc.) i.e.:
| condition |
condition := 10 > (3 + 4). "=> true"
condition
ifTrue: [
Transcript show: '10 > 7. That''s good.']
ifFalse: [
Transcript show: 'I think something''s wrong....'].
[Sensor anyButtonPressed] whileFalse: [
World displayWorldSafely].• Other functions which take an argument which must be evaluated later, multiple times, or with complex argument(s), e.i.:
| block |
block := [:str |
Transcript show: str.
World addMorphFront: (StringMorph new contents: str).
'=> ', str, ' <='].
block value: 'Hi there, ', (Time now) asString
Last edited by nXIII (2010-09-07 17:21:11)
Offline
Excellent Squeak Smalltalk intro, well done, nXIII! All Scratch modders should begin to learn the language in ways like this! How about enhancing it by giving an oversight of the built-in tools (browsers for classes, methods - sender, implementors, versions, workspaces, change sorters, inspectors, and doIt, printIt, inspectIt etc.)?
Offline
Jens wrote:
Excellent Squeak Smalltalk intro, well done, nXIII! All Scratch modders should begin to learn the language in ways like this! How about enhancing it by giving an oversight of the built-in tools (browsers for classes, methods - sender, implementors, versions, workspaces, change sorters, inspectors, and doIt, printIt, inspectIt etc.)?
Don't worry, this was my late-night attempt at it, this is just the start!
Offline
I think this is helpful for people to learn Squeak before they embark on their own mod, so I'll bump it up from the 8th page.
Offline
Nice tutorial! Thanks!

Offline
nXIII wrote:
I'll try to update it soon with more tutorials
It's a good thing I bumped it earlier
Offline
THat first post is the longest one I've ever seen, I think.
Offline
The person above me wrote:
THat first post is the longest one I've ever seen, I think.p
Wanna see a longer one?
Then today is your lucky day.
Click Me! PUUHHHLLLEEEEAAAAASSEEEE!!
Last edited by Jwosty (2010-08-10 16:12:46)
Google it.
Offline
I know understand one a type of block in Squeak. Here's me starting to try it:
| lorem |
lorem _ [:ipsum |
self inform: ipsum].
(lorem value: 'A message box. Click OK.').EDIT: How do you call a block that takes more than one argument?
Last edited by ThePCKid (2010-09-06 21:41:39)
Offline
ThePCKid wrote:
I know understand one a type of block in Squeak. Here's me starting to try it:
Code:
| lorem | lorem _ [:ipsum | self inform: ipsum]. (lorem value: 'A message box. Click OK.').EDIT: How do you call a block that takes more than one argument?
with "block value: arg_1 value: arg_2 ... value: arg_n"
Last edited by nXIII (2010-09-07 15:48:06)
Offline
nXIII wrote:
ThePCKid wrote:
I know understand one a type of block in Squeak. Here's me starting to try it:
Code:
| lorem | lorem _ [:ipsum | self inform: ipsum]. (lorem value: 'A message box. Click OK.').EDIT: How do you call a block that takes more than one argument?
with "block value: arg_1 value: arg_2 ... value: arg_n"
Thanks!
I know that this is off topic, but Squeak has just released it's 10,500th update! If you download the alpha and then update it then you'll know what I'm talking about.
Offline
Found an error in one of your examples!
Original:
| condition |
condition := 10 > 3 + 4. "=> true"
condition
ifTrue: [
Transcript show: '10 > 7. That's good.']
ifFalse: [
Transcript show: 'I think something's wrong....'].
[Sensor anyButtonPressed] whileFalse: [
World displayWorldSafely].Fixed:
| condition |
condition := 10 > (3 + 4). "=> true"
condition
ifTrue: [
Transcript show: '10 > 7. That''s good.']
ifFalse: [
Transcript show: 'I think something''s wrong....'].
[Sensor anyButtonPressed] whileFalse: [
World displayWorldSafely].You forgot to escape the apostrophe. You also forgot something else.
Last edited by ThePCKid (2010-09-07 17:15:06)
Offline