Presentation is loading. Please wait.

Presentation is loading. Please wait.

Tutorial: Squeak — An Open-Source Smalltalk Environment Oscar Nierstrasz scg.unibe.ch TOOLS Europe 2008 Zürich, July 1, 2008.

Similar presentations


Presentation on theme: "Tutorial: Squeak — An Open-Source Smalltalk Environment Oscar Nierstrasz scg.unibe.ch TOOLS Europe 2008 Zürich, July 1, 2008."— Presentation transcript:

1 Tutorial: Squeak — An Open-Source Smalltalk Environment Oscar Nierstrasz scg.unibe.ch TOOLS Europe 2008 Zürich, July 1, 2008

2 © O. Nierstrasz 2 Roadmap  What is Smalltalk?  Getting started  Syntax in a nutshell  Test-driven development  Version control  Standard classes — Object, Number, Boolean …  Common idioms  Debugging practices  Metaclasses in 7 points  Seaside demo

3 © O. Nierstrasz 3 Roadmap  What is Smalltalk?  Getting started  Syntax in a nutshell  Test-driven development  Version control  Standard classes — Object, Number, Boolean …  Common idioms  Debugging practices  Metaclasses in 7 points  Seaside demo

4 © O. Nierstrasz 4 The origins of Smalltalk Alan Kay’s Dynabook project (1968) Alto — Xerox PARC (1973)

5 © O. Nierstrasz 5 What is Smalltalk? Image Changes + Virtual machine Sources +

6 © O. Nierstrasz 6 Smalltalk-80 and Squeak Everything is an object Everything is there, all the time First windowing system with mouse First graphical IDE Squeak: a modern, portable, fast, open- source Smalltalk

7 © O. Nierstrasz 7 Squeak resources Free download — Print-on-demand SqueakByExample.org www.squeak.org Downloads and links www.seaside.st One-click image

8 © O. Nierstrasz 8 Don’t panic! New Smalltalkers often think they need to understand all the details of a thing before they can use it. Try to answer the question “How does this work?” with “I don’t care”. — Alan Knight. Smalltalk Guru

9 © O. Nierstrasz 9 Roadmap  What is Smalltalk?  Getting started  Syntax in a nutshell  Test-driven development  Version control  Standard classes — Object, Number, Boolean …  Common idioms  Debugging practices  Metaclasses in 7 points  Seaside demo

10 Everything is an object

11 Everything happens by sending messages

12 © O. Nierstrasz 12 Running Squeak

13 © O. Nierstrasz 13 Three-button mouse Select Operate Window

14 © O. Nierstrasz 14 World Menu and Open Menu

15 © O. Nierstrasz 15 Standard development tools

16 © O. Nierstrasz 16 Debuggers, Inspectors, Explorers

17 © O. Nierstrasz 17 Do it, Print it, … You can evaluate any expression anywhere in Smalltalk.

18 © O. Nierstrasz 18 Roadmap  What is Smalltalk?  Getting started  Syntax in a nutshell  Test-driven development  Version control  Standard classes — Object, Number, Boolean …  Common idioms  Debugging practices  Metaclasses in 7 points  Seaside demo

19 © O. Nierstrasz 19 Three kinds of messages > Unary messages > Binary messages > Keyword messages 5 factorial Transcript cr 3 + 4 3 raisedTo: 10 modulo: 5 Transcript show: 'hello world'

20 © O. Nierstrasz 20 Precedence 2 raisedTo: 1 + 3 factorial 1 + 2 * 3 1 + (2 * 3) 128 9(!) 7 First unary, then binary, then keyword: Use parentheses to force order: 2 raisedTo: (1 + (3 factorial)) Same as:

21 © O. Nierstrasz 21 A typical method in the class Point <= aPoint "Answer whether the receiver is neither below nor to the right of aPoint." ^ x <= aPoint x and: [y <= aPoint y] (2@3) <= (5@6) true Method nameArgumentComment Return Binary message Keyword messageInstance variable Block

22 © O. Nierstrasz 22 Statements and cascades | p pen | p := 100@100. pen := Pen new. pen up. pen goto: p; down; goto: p+p Temporary variables Statement Cascade

23 © O. Nierstrasz 23 Literals and constants Strings & Characters'hello' $a Numbers1 3.14159 Symbols#yadayada Arrays#(1 2 3) Pseudo-variablesself super Constantstrue false

24 © O. Nierstrasz 24 Method Return  Use a caret to return a value from a method or a block  By default, methods return self max: aNumber ^ self < aNumber ifTrue: [aNumber] ifFalse: [self] 1 max: 2 2

25 © O. Nierstrasz 25 Blocks  Use square brackets to delay evaluation of expressions ^ 1 < 2 ifTrue: ['smaller'] ifFalse: ['bigger'] 'smaller'

26 © O. Nierstrasz 26 Variables  Local variables are delimited by |var| Block variables by :var| OrderedCollection>>collect: aBlock "Evaluate aBlock with each of my elements as the argument." | newCollection | newCollection := self species new: self size. firstIndex to: lastIndex do: [ :index | newCollection addLast: (aBlock value: (array at: index))]. ^ newCollection (OrderedCollection with: 10 with: 5) collect: [:each| each factorial ] an OrderedCollection(3628800 120)

27 © O. Nierstrasz 27 Control Structures  Every control structure is realized by message sends max: aNumber ^ self < aNumber ifTrue: [aNumber] ifFalse: [self] 4 timesRepeat: [Beeper beep]

28 © O. Nierstrasz 28 Creating objects  Class methods  Factory methods OrderedCollection new Array with: 1 with: 2 1@2 1/2 a Point a Fraction

29 © O. Nierstrasz 29 Creating classes  Send a message to a class (!) Number subclass: #Complex instanceVariableNames: 'real imaginary' classVariableNames: '' poolDictionaries: '' category: 'ComplexNumbers'

30 © O. Nierstrasz 30 Roadmap  What is Smalltalk?  Getting started  Syntax in a nutshell  Test-driven development  Version control  Standard classes — Object, Number, Boolean …  Common idioms  Debugging practices  Metaclasses in 7 points  Seaside demo

31 © O. Nierstrasz 31 Change sets

32 © O. Nierstrasz 32 SUnit

33 © O. Nierstrasz 33 Money TestCase subclass: #MoneyTest instanceVariableNames: 'chf2 chf8 chf10' classVariableNames: '' poolDictionaries: '' category: 'Money'  We will implement the Money example in Smalltalk —First, we develop a test case for a single currency NB: This is just a message sent to the TestCase class object (!)

34 © O. Nierstrasz 34 SetUp  We will need setters for the private Money state MoneyTest>>setUp chf2 := Money new currency: 'CHF'; amount: 2. chf8 := Money new currency: 'CHF'; amount: 8. chf10 := Money new currency: 'CHF'; amount: 10.

35 © O. Nierstrasz 35 MoneyTest>>testEquals  Some obvious tests MoneyTest>>testEquals self assert: chf2 = chf2. self assert: chf2 = (Money new currency: 'CHF'; amount: 2). self assert: chf2 ~= chf8.

36 © O. Nierstrasz 36 Money  We define Money as a subclass of Object, with getters and setters Object subclass: #Money instanceVariableNames: 'currency amount' classVariableNames: '' poolDictionaries: '' category: 'Money' Money>>currency: aString currency := aString. Money>>currency ^ currency

37 © O. Nierstrasz 37 Failing tests

38 © O. Nierstrasz 38 Comparisons Money>>= aMoney ^ self currency = aMoney currency and: [ self amount = aMoney amount ]

39 © O. Nierstrasz 39 Constructors MoneyTest>>testEquals self assert: chf2 = chf2. self assert: chf2 = (Money currency: 'CHF' amount: 2). self assert: chf2 != chf8. We need a constructor on the class side of Money

40 © O. Nierstrasz 40 Class methods NB: Which “self” is referred to in the method body?

41 © O. Nierstrasz 41 Addition Money>>+ aMoney ^ Money currency: self currency amount: self amount + aMoney amount MoneyTest>>testAdd self assert: chf2 + chf8 = chf10 And so on …

42 © O. Nierstrasz 42 Filing out your changes  You can “file out” all your changes so they can be loaded into another image

43 © O. Nierstrasz 43 Change Sets 'From Squeak3.9alpha of 4 July 2005 [latest update: #7006] on 7 March 2006 at 12:52:26 pm'! Object subclass: #Money instanceVariableNames: 'currency amount' classVariableNames: '' poolDictionaries: '' category: 'Money'! !Money commentStamp: 'on 3/7/2006 12:45' prior: 0! SUnit demo! TestCase subclass: #MoneyTest instanceVariableNames: 'chf2 chf8 chf10' classVariableNames: '' poolDictionaries: '' category: 'Money'! !MoneyTest commentStamp: 'on 3/7/2006 12:44' prior: 0! SUnit demo! !Money methodsFor: 'arithmetic' stamp: 'on 3/7/2006 12:52'! + aMoney ^ Money currency: self currency amount: self amount + aMoney amount! ! …

44 © O. Nierstrasz 44 Extensions  Creating new instances of Money is still cumbersome —We would like to be able to write instead code like this: TestMoney>>setUp chf2 := 2 chf. chf8 := 8 chf. chf10 := 10 chf.

45 © O. Nierstrasz 45 Extension protocols  To extend an existing class for a category MyProject, define the method category *MyProject for that class.

46 © O. Nierstrasz 46 Roadmap  What is Smalltalk?  Getting started  Syntax in a nutshell  Test-driven development  Version control  Standard classes — Object, Number, Boolean …  Common idioms  Debugging practices  Metaclasses in 7 points  Seaside demo

47 © O. Nierstrasz 47 SqueakSource.com

48 © O. Nierstrasz 48 Categories, Projects and Packages  A system category MyProject (and possibly MyProject-*) contains the classes of your application  A Monticello package MyProject contains the categories MyProject and MyProject-*  A SqueakSource project MyProject stores everything in the Monticello package MyProject

49 © O. Nierstrasz 49 Loading a project  To load a project from SqueakSource.com —Find the project in SqueakSource —Open the Monticello Browser —Add an HTTP Repository – Accept the code fragment from the SqueakSource page —Open the repository and load the latest version

50 © O. Nierstrasz 50 Loading a project

51 © O. Nierstrasz 51 Creating a project  To create a project on SqueakSource.com —Define your categories MyProject or MyProject-* —Create a SqueakSource project MyProject —Define a Monticello package MyProject —Add an HTTP Repository for MyProject – Accept the code fragment from the SqueakSource page —Save the the package

52 © O. Nierstrasz 52 Roadmap  What is Smalltalk?  Getting started  Syntax in a nutshell  Test-driven development  Version control  Standard classes — Object, Number, Boolean …  Common idioms  Debugging practices  Metaclasses in 7 points  Seaside demo

53 © O. Nierstrasz 53 Object Defines common behavior for all the objects in the system.

54 © O. Nierstrasz 54 Identity vs. Equality  = tests Object value —Should normally be overridden – Default implementation is == ! —You should override hash too!  == tests Object identity —Should never be overridden 'foo','bar' = 'foobar' 'foo','bar' == 'foobar' true false

55 © O. Nierstrasz 55 Printing  Override printOn: to give your objects a sensible textual representation Fraction>>printOn: aStream aStream nextPut: $(. numerator printOn: aStream. aStream nextPut: $/. denominator printOn: aStream. aStream nextPut: $).

56 © O. Nierstrasz 56 Object methods to support the programmer error: aString Signal an error doesNotUnderstand: aMessage Handle unimplemented message halt, halt: aString Invoke the debugger subclassResponsibility The sending method is abstract shouldNotImplement Disable an inherited method deprecated: anExplanationString Warn that the sending method is deprecated.

57 © O. Nierstrasz 57 Numbers

58 © O. Nierstrasz 58 Abstract methods in Smalltalk Number>>+ aNumber "Answer the sum of the receiver and aNumber." self subclassResponsibility Object>>subclassResponsibility "This message sets up a framework for the behavior of the class' subclasses. Announce that the subclass should have implemented this message." self error: 'My subclass should have overridden ', thisContext sender selector printString

59 © O. Nierstrasz 59 Strings

60 © O. Nierstrasz 60 Strings  To introduce a single quote inside a string, just double it. #mac asString 12 printString String with: $A 'can''t' at: 4 'hello', ' ', 'world' 'mac' '12' 'A' $' 'hello world'

61 © O. Nierstrasz 61 Comments and Tips "TestRunner open" Use comments to provide useful “doits” —Avoid putting a space between the " and the first character!

62 © O. Nierstrasz 62 Literal and dynamic arrays #(1 + 2. 3 ) #(1 #+ 2 #. 3) { 1 + 2. 3 } Array with: 1+2 with: 3 #(3 3) { … } is a shortcut for Array with: … Literal arrays Dynamic arrays

63 © O. Nierstrasz 63 Symbols vs. Strings  Symbols are used as method selectors and unique keys for dictionaries —Symbols are read-only objects, strings are mutable —A symbol is unique, strings are not NB: Comparing strings is slower than comparing symbols by a factor of 5 to 10. However, converting a string to a symbol is more than 100 times more expensive. 'cal', 'vin' == 'calvin'. ('cal', 'vin') asSymbol == #calvin. false true

64 © O. Nierstrasz 64 Blocks  Syntax: —Returns last expression of the block [ :arg1 :arg2 | |temp1 temp2| expression. expression ] [2 + 3 + 4 + 5] value [:x | x + 3 + 4 + 5 ] value: 2 [:x :y | x + y + 4 + 5] value: 2 value: 3 [:x :y :z | x + y + z + 5] value: 2 value: 3 value: 4 [:x :y :z :w | x + y + z + w] value: 2 value: 3 value: 4 value: 5

65 © O. Nierstrasz 65 Booleans

66 © O. Nierstrasz 66 IfTrue: IfFalse: Integer>>factorial "Answer the factorial of the receiver." self = 0 ifTrue: [^ 1]. self > 0 ifTrue: [^ self * (self - 1) factorial]. self error: 'Not valid for negative integers'

67 © O. Nierstrasz 67 nil A reference to the UndefinedObject true Singleton instance of the class True false Singleton instance of the class False self Reference to this object Method lookup starts from object’s class super Reference to this object (!) Method lookup starts from the superclass thisContext Reification of execution context Six Pseudo-Variables  The following pseudo-variables are hard-wired into the Smalltalk compiler.

68 © O. Nierstrasz 68 Control Constructs  All control constructs in Smalltalk are implemented by sending messages —No keywords —Open, extensible —Built up from Booleans, Numbers, Collections and Blocks

69 © O. Nierstrasz 69 Various kinds of Loops |n| n:= 10. [n>0] whileTrue: [ Transcript show: n; cr. n:=n-1] 1 to: 10 do: [:n | Transcript show: n; cr ] (1 to: 10) do: [:n | Transcript show: n; cr ] 10 timesRepeat: [ Transcript show: 'hi'; cr ] In each case, what is the target object?

70 © O. Nierstrasz 70 Collections Resist the temptation to program your own collections!

71 © O. Nierstrasz 71 Common messages #(1 2 3 4) includes: 5 #(1 2 3 4) size #(1 2 3 4) isEmpty #(1 2 3 4) contains: [:some | some < 0 ] #(1 2 3 4) do: [:each | Transcript show: each ] #(1 2 3 4) with: #(5 6 7 8) do: [:x : y | Transcript show: x+y; cr] #(1 2 3 4) select: [:each | each odd ] #(1 2 3 4) reject: [:each | each odd ] #(1 2 3 4) detect: [:each | each odd ] #(1 2 3 4) collect: [:each | each even ] #(1 2 3 4) inject: 0 into: [:sum :each | sum + each] false 4 #(1 3) #(2 4) 1 {false.true.false.true} 10

72 © O. Nierstrasz 72 Iteration — the hard road and the easy road |aCol result| aCol := #( 2 -3 4 -35 4 -11). result := aCol species new: aCol size. 1 to: aCol size do: [ :each | result at: each put: (aCol at: each) abs]. result #(2 3 4 35 4 11) #( 2 -3 4 -35 4 -11) collect: [:each | each abs ] #(2 3 4 35 4 11) How to get absolute values of a collection of integers? NB: The second solution also works for indexable collections and sets.

73 © O. Nierstrasz 73 Concatenation How do you put two collections together?  Send “,” to the first with the second as argument (1 to: 3), (4 to: 6) a Dictionary(#a->1 #b->2 ) (Dictionary newFrom: { #a -> 1}), (Dictionary newFrom: { #b -> 2}) #(1 2 3 4 5 6)

74 © O. Nierstrasz 74 Sorted Collection How do you sort a collection?  Convert it to a Sorted Collection. 'hello' asSortedCollection a SortedCollection($o $l $l $h $e) 'hello' asSortedCollection: [:a :b | b<=a ] a SortedCollection($e $h $l $l $o)

75 © O. Nierstrasz 75 Duplicate Removing Set How do you remove the duplicates from a Collection?  Convert it to a Set 'hello world' asSet a Set(Character space $r $d $e $w $h $l $o)

76 © O. Nierstrasz 76 Converting  Send asSet, asBag, asSortedCollection etc. to convert between kinds of collections  Send keys, values to extract collections from dictionaries  Use various factory methods to build new kinds of collections from old Dictionary newFrom: {1->#a. 2->#b. 3->#c}

77 © O. Nierstrasz 77 Roadmap  What is Smalltalk?  Getting started  Syntax in a nutshell  Test-driven development  Version control  Standard classes — Object, Number, Boolean …  Common idioms  Debugging practices  Metaclasses in 7 points  Seaside demo

78 © O. Nierstrasz 78 Snakes and Ladders See: http://en.wikipedia.org/wiki/Snakes_and_ladders

79 © O. Nierstrasz 79 Scripting a use case SnakesAndLadders class>>example "self example playToEnd" ^ (self new) add: FirstSquare new; add: (LadderSquare forward: 4); add: BoardSquare new; add: (LadderSquare forward: 2); add: BoardSquare new; add: (SnakeSquare back: 6); add: BoardSquare new; join: (GamePlayer named: 'Jack'); join: (GamePlayer named: 'Jill'); yourself  Construct the board  Add some players  Play the game

80 © O. Nierstrasz 80 Distributing responsibilities

81 © O. Nierstrasz 81 Lots of Little Methods  Once and only once —“In a program written with good style, everything is said once and only once.”  Lots of little pieces —“Good code invariably has small methods and small objects. Only by factoring the system into many small pieces of state and function can you hope to satisfy the ‘once and only once’ rule.” – Kent Beck, Smalltalk Best Practice Patterns

82 © O. Nierstrasz 82 Composed Method How do you divide a program into methods?  Divide your program into methods that perform one identifiable task. —Keep all of the operations in a method at the same level of abstraction. —This will naturally result in programs with many small methods, each a few lines long.

83 © O. Nierstrasz 83 Snakes and Ladders methods 68 methods only 7 are more than 6 LOC (including comments!) — 1 of these is the “main” method — the other 6 are test methods

84 © O. Nierstrasz 84 How to initialize objects? In Smalltalk, —methods are public, and —instance variables are private So, how can a class (an object) initialize the instance variables of its instances (other objects)?

85 © O. Nierstrasz 85 Explicit Initialization How do you initialize instance variables to their default values?  Implement a method initialize that sets all the values explicitly. — Override the class message new to invoke it on new instances SnakesAndLadders>>initialize super initialize. die := Die new. squares := OrderedCollection new. players := OrderedCollection new. turn := 1. over := false.

86 © O. Nierstrasz 86  In Squeak 3.9, the method new calls initialize by default.  NB: You can override new, but you should never override basicNew!  Every metaclass ultimately inherits from Behaviour – More on this later … Behavior>>new ^ self basicNew initialize Who calls initialize?

87 © O. Nierstrasz 87 Constructor Method How do you represent instance creation?  Provide methods in the class side “instance creation” protocol that create well-formed instances. Pass all required parameters to them. LadderSquare class>>forward: number ^ self new setForward: number SnakeSquare class>>back: number ^ self new setBack: number

88 © O. Nierstrasz 88 Constructor Parameter Method How do you set instance variables from the parameters to a Constructor Method?  Code a single method that sets all the variables. Preface its name with “set”, then the names of the variables. SnakeSquare>>setBack: aNumber back := aNumber. BoardSquare>>setPosition: aNumber board: aBoard position := aNumber. board := aBoard LadderSquare>>setForward: aNumber forward := aNumber.

89 © O. Nierstrasz 89 Debug Printing Method How do you code the default printing method? —There are two audiences: – you (wanting a lot of information) – your clients (wanting only external properties)  Override printOn: to provide information about object’s structure to the programmer —Put printing methods in the “printing” protocol

90 © O. Nierstrasz 90 Viewing the game state SnakesAndLadders example inspect In order to provide a simple way to monitor the game state and to ease debugging, we need a textual view of the game

91 © O. Nierstrasz 91 Implementing printOn: SnakesAndLadders>>printOn: aStream squares do: [:each | each printOn: aStream] BoardSquare>>printOn: aStream aStream nextPutAll: '[', position printString, self contents, ']' LadderSquare>>printOn: aStream super printOn: aStream. aStream nextPutAll: forward asString, '+>' SnakeSquare>>printOn: aStream aStream nextPutAll: '<-', back asString. super printOn: aStream GamePlayer>>printOn: aStream aStream nextPutAll: name

92 © O. Nierstrasz 92 Viewing the game state SnakesAndLadders example inspect

93 © O. Nierstrasz 93 Interacting with the game With a bit of care, the Inspector can serve as a basic GUI for objects we are developing

94 © O. Nierstrasz 94 Query Method How do you represent testing a property of an object?  Provide a method that returns a Boolean. —Name it by prefacing the property name with a form of “be” — is, was, will etc.

95 © O. Nierstrasz 95 Some query methods SnakesAndLadders>>isNotOver ^ self isOver not BoardSquare>>isFirstSquare ^ position = 1 BoardSquare>>isLastSquare ^ position = board lastPosition BoardSquare>>isOccupied ^ player notNil FirstSquare>>isOccupied ^ players size > 0

96 © O. Nierstrasz 96 Constant Method How do you code a constant?  Create a method that returns the constant Fraction>>one ^ self numerator: 1 denominator: 1

97 © O. Nierstrasz 97 Roadmap  What is Smalltalk?  Getting started  Syntax in a nutshell  Test-driven development  Version control  Standard classes — Object, Number, Boolean …  Common idioms  Debugging practices  Metaclasses in 7 points  Seaside demo

98 © O. Nierstrasz 98 Debug printing  Basic printing —You can use the Transcript to display progress  Optional printing —Use a global or a class to control printing information Transcript cr; show: ‘The total= ’, self total printString. Debug ifTrue: [Transcript show: self total printString] Debug > 4 ifTrue: [Transcript show: self total printString] Debug print: [Transcript show: self total printString]

99 © O. Nierstrasz 99 Tests are your friends!  Resist the temptation to write debugging print methods —Write a test instead!  Resist the temptation to evaluate ad hoc expressions in a Workspace —Write a test instead! —Tests are reusable – You will have to spend the effort debugging anyway – Amortize the investment by coding your debugging effort as tests

100 © O. Nierstrasz 100 The Inspector is your friend!  You can inspect anything —Inspect any expression —View the printString state —Interact with any object —Inspect instance variables —Navigate through the system

101 © O. Nierstrasz 101 Use the Inspector to make ad hoc changes  You can use the Inspector as an ad hoc interface to modify the state of a running system —Use this sparingly! If we change the name of a GamePlayer, this will be reflected in the running system.

102 © O. Nierstrasz 102 Breakpoints  Send the message self halt to start the debugger at an arbitrary location SnakesAndLadders>>playOneMove | result | self assert: self invariant. self halt. ^ self isOver …

103 © O. Nierstrasz 103 The Debugger is your friend! Everything is an object!  You can: —Inspect any entity —Evaluate any code —Modify code on the fly Don’t forget: —Keep the Debugger open!

104 © O. Nierstrasz 104 Dangling self halt  When you have finished debugging, don’t forget to remove any self halt in the code! —Running all the tests should catch this!

105 © O. Nierstrasz 105 SystemNavigation default browseMethodsWithSourceString: 'super' A bit slow, and contains many false negatives The Browser is your friend! How can we browse all methods that send to super? —Browse “browse” —Object>>browse —Object>>systemNavigation —SystemNavigation —SystemNavigation>>browseMethodsWithSourceString:

106 © O. Nierstrasz 106 The Message Name Finder is your friend!  We continue browsing: —SystemNavigation>>browseMethodsWith* —SystemNavigation>>browseAllSelect:  Query the Message Name Finder for “super” —Yields CompiledMethod>>sendsToSuper  Better solution: SystemNavigation default browseAllSelect: [:method | method sendsToSuper ] Fast, and accurate!

107 © O. Nierstrasz 107 Roadmap  What is Smalltalk?  Getting started  Syntax in a nutshell  Test-driven development  Version control  Standard classes — Object, Number, Boolean …  Common idioms  Debugging practices  Metaclasses in 7 points  Seaside demo

108 © O. Nierstrasz 108 Metaclasses in 7 points 1. Every object is an instance of a class 2. Every class eventually inherits from Object 3. Every class is an instance of a metaclass 4. The metaclass hierarchy parallels the class hierarchy 5. Every metaclass inherits from Class and Behavior 6. Every metaclass is an instance of Metaclass 7. The metaclass of Metaclass is an instance of Metaclass Adapted from Goldberg & Robson, Smalltalk-80 — The Language

109 © O. Nierstrasz 109 1. Every object is an instance of a class Remember the Snakes and Ladders Board Game …

110 © O. Nierstrasz 110 2. Every class inherits from Object Caveat: in Squeak, Object has a superclass called ProtoObject aSnakeSquare is-a SnakeSquare and is-a BoardSquare and is-an Object

111 © O. Nierstrasz 111 Method lookup follows the inheritance chain

112 © O. Nierstrasz 112 3. Every class is an instance of a metaclass

113 © O. Nierstrasz 113 4. The metaclass hierarchy parallels the class hierarchy

114 © O. Nierstrasz 114 Classes are objects too … back: is a Snake constructor method

115 © O. Nierstrasz 115 5. Every metaclass inherits from Class and Behavior Every class is-a Class

116 © O. Nierstrasz 116 6. Every metaclass is an instance of Metaclass © Oscar Nierstrasz

117 © O. Nierstrasz 117 7. The metaclass of Metaclass is an instance of Metaclass

118 © O. Nierstrasz 118 Roadmap  What is Smalltalk?  Getting started  Syntax in a nutshell  Test-driven development  Version control  Standard classes — Object, Number, Boolean …  Common idioms  Debugging practices  Metaclasses in 7 points  Seaside demo

119 © O. Nierstrasz 119 Attribution-ShareAlike 3.0 Unported You are free: to Share — to copy, distribute and transmit the work to Remix — to adapt the work Under the following conditions: Attribution. You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work). Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under the same, similar or a compatible license. For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to this web page. Any of the above conditions can be waived if you get permission from the copyright holder. Nothing in this license impairs or restricts the author's moral rights. License  http://creativecommons.org/licenses/by-sa/3.0/

120 © O. Nierstrasz 120 Variables  Shared variables — initial uppercase  Private variables — initial lowercase variable Shared variable Pool variable Global variable private variable named temporary variableinstance variable indexed | block temporary | | method temporary | Class variable method parameter : block parameter

121 © O. Nierstrasz 121 Initializing class variables  Class variables should be initialized by an initialize method on the class side Magnitude subclass: #Date instanceVariableNames: 'julianDayNumber ' classVariableNames: 'DaysInMonth FirstDayOfMonth MonthNames SecondsInDay WeekDayNames ' poolDictionaries: '' category: 'Kernel-Magnitudes' Date class>>initialize... WeekDayNames := #(Sunday Monday...). MonthNames := #(January February... ). DaysInMonth := #(31 28 31 30 31 30 31 31 30 31 30 31).

122 © O. Nierstrasz 122 ClassVariables vs. Instance Variables


Download ppt "Tutorial: Squeak — An Open-Source Smalltalk Environment Oscar Nierstrasz scg.unibe.ch TOOLS Europe 2008 Zürich, July 1, 2008."

Similar presentations


Ads by Google