Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Advanced Object Oriented Systems (CM0318) Lecture 8 (Last updated 15th February 2002)

Similar presentations


Presentation on theme: "1 Advanced Object Oriented Systems (CM0318) Lecture 8 (Last updated 15th February 2002)"— Presentation transcript:

1 1 Advanced Object Oriented Systems (CM0318) Lecture 8 (Last updated 15th February 2002)

2 2 Purpose of Lectures 8 & 9 To illustrate why Smalltalk is different, in particular because: –implementation of system classes is readily available –debugging tends to involve understanding system classes as well as one’s own –Smalltalk is a highly dynamic system

3 3 Topics Implementation of collections Introspection and dynamic modification of classes/objects The Model-View-Controller paradigm Debugging strategies (Implementation & introspection are the topics of the present lecture)

4 4 Partial Collection hierarchy ProtoObject Objectat: at:put: Collectionincludes: isEmpty add: remove: do: size Bag SequenceableCollection, first at:ifAbsent: indexOf: ArrayedCollection Array(“Variable subclass”) String< = beginsWith: Symbol OrderedCollection Set Dictionaryat: at:put: includesKey:

5 5 Recommended Smalltalk reading Byte, August 1981 (dedicated to Smalltalk) Goldberg, A., and Robson, D., ‘Smalltalk- 80 : the language’, Addison-Wesley, 1989. Goldberg, A., ‘Smalltalk-80 : the interactive programming environment’, Addison- Wesley, 1984.

6 6 Implementation of Collections NB it’s essential to annotate these handouts - otherwise the code won’t make much sense!! You can verify all of what I am telling you in this lecture simply by browsing in Squeak - indeed, the main message is the ‘openness’ of the Smalltalk code. We’ll see how this affects debugging, etc., later.

7 7 Implementation of Array Creation method: class method new:, which is actually inherited from Behavior (Remember Array is itself an object; instance of its metaclass, which is a subclass - with a few intermediaries in between - of Behavior).

8 8 Array (ctd.) Main accessing methods: at: (implemented in Object), at:put: (implemented in Object), size (implemented in ArrayedCollection) Example of code to replace every element in an array by that element + 1: a ← #(3 4 5). 1 to: a size do: [:i|a at: i put: (a at: i) + 1]. ^a

9 9 Array (ctd.) Source code for Object>>at:put: at: index put: value "Primitive. Assumes receiver is indexable. Store the argument value in the indexable element of the receiver indicated by index. Fail if the index is not an Integer or is out of bounds. Or fail if the value is not of the right type for this kind of collection. Answer the value that was stored. Essential. See Object documentation whatIsAPrimitive." index isInteger ifTrue: [self class isVariable ifTrue: [(index >= 1 and: [index <= self size]) ifTrue: [self errorImproperStore] ifFalse: [self errorSubscriptBounds: index]] ifFalse: [self error: (self class name), 's are not indexable']]. index isNumber ifTrue: [^self at: index asInteger put: value] ifFalse: [self errorNonIntegerIndex]

10 10 Array (ctd.) Methods like at:, at:put: are defined in Object because there are 2 fundamental types of class: Fixed (named instance variables only) –Defined subclass: #... Variable (named instance variables and subscripted instance variables) –Defined variableSubclass: #...

11 11 FIXED Inst var 1 Inst var 2 Inst var 3Inst var 4Inst var 5 Inst var n-1 Inst var n VARIABLE Inst var 1Inst var 2Inst var 3Inst var 4Inst var 5 Inst var n-1 Inst var n 123m

12 12 Array (ctd.) Testing for equality (inherited from SequenceableCollection) = otherCollection "Answer true if the receiver is equivalent to the. First test for identity, then rule out different species and sizes of collections. As a last resort, examine each element of the receiver and the." | size | self == otherCollection ifTrue: [^ true]. (self species == otherCollection species) ifFalse: [^ false]. (size ← self size) = otherCollection size ifFalse: [^ false]. 1 to: size do: [:index | (self at: index) = (otherCollection at: index) ifFalse: [^ false]]. ^ true

13 13 Array (ctd.) Testing for inclusion (inherited from Collection): includes: anObject "Answer whether anObject is one of the receiver's elements." self do: [:each | anObject = each ifTrue: [^true]]. ^false

14 14 Array (ctd.) Iteration - do: (inherited from SequenceableCollection) do: aBlock "Refer to the comment in Collection|do:." 1 to: self size do: [:index | aBlock value: (self at: index)]

15 15 OrderedCollection Similar to Vector in Java Comprises an Array, a firstIndex and a lastIndex (only part of the array is used). So an ordered collection with elements 34, 46, 25 might be represented thus: Element noContents 1? 2? 334<- firstIndex=3 446 525<- lastIndex=5 6? 7?

16 16 Compared with Vector... Allows the collection to grow at the beginning and the end.

17 17 OrderedCollection example oc ← #(3 4 5) asOrderedCollection. oc addFirst: 'ho'. oc addLast: 'hoho'. ^oc at: 2 Result is 3.

18 18 OrderedCollection (ctd.) Instance creation (class methods): new ^self new: 10 new: anInteger "If a subclass adds fields, then it is necessary for that subclass to reimplement new:." ^ super new setCollection: (Array new: anInteger)

19 19 OrderedCollection (ctd.) Instance creation (instance methods): setCollection: anArray array ← anArray. self reset reset firstIndex ← array size // 3 max: 1. lastIndex ← firstIndex - 1

20 20 OrderedCollection (ctd.) Accessing using at: at: anInteger "Answer my element at index anInteger. at: is used by a knowledgeable client to access an existing element" (anInteger lastIndex]) ifTrue: [self errorNoSuchElement] ifFalse: [^ array at: anInteger + firstIndex - 1]

21 21 OrderedCollection (ctd.) Adding a new element: addLast: newObject "Add newObject to the end of the receiver. Answer newObject." lastIndex = array size ifTrue: [self makeRoomAtLast]. lastIndex ← lastIndex + 1. array at: lastIndex put: newObject. ^ newObject

22 22 OrderedCollection (ctd.) Growing... makeRoomAtLast | newLast delta | newLast ← self size. array size - self size = 0 ifTrue: [self grow]. (delta ← firstIndex - 1) = 0 ifTrue: [^ self]. "we might be here under false premises or grow did the job for us" 1 to: newLast do: [:index | array at: index put: (array at: index + delta). array at: index + delta put: nil]. firstIndex ← 1. lastIndex ← newLast

23 23 OrderedCollection (ctd.) More growing: grow "Become larger. Typically, a subclass has to override this if the subclass adds instance variables." | newArray | newArray ← Array new: self size + self growSize. newArray replaceFrom: 1 to: array size with: array startingAt: 1. array ← newArray

24 24 Exercise (unassessed) Investigate: –Other methods implemented by/inherited by Array and OrderedCollection –The implementation of the Set class

25 25 Introspection; dynamic modification to classes/objects Java provides limited introspection via the reflection API. Main things you can do: –determine an object’s class –get information about a class’ fields, methods, etc. –create an instance of a class whose name is only determined at run-time –get and set the value of an object’s field –invoke a method on an object these things can be achieved even if the method name, for example, is only determined at run-time

26 26 Suggested reading Tutorial on Java reflection: http://web2.java.sun.com/docs/books/tutorial/reflect/index.html

27 27 Example: invoking a method import java.lang.reflect.*; class SampleInvoke { public static void main(String[] args) { String firstWord = "Hello "; String secondWord = "everybody."; String bothWords = append(firstWord, secondWord); System.out.println(bothWords); }

28 28 public static String append(String firstWord, String secondWord) { String result = null; Class c = String.class; Class[] parameterTypes = new Class[] {String.class}; Method concatMethod; Object[] arguments = new Object[] {secondWord}; try { concatMethod = c.getMethod("concat", parameterTypes); result = (String) concatMethod.invoke(firstWord, arguments); } catch (NoSuchMethodException e) { System.out.println(e); } catch (IllegalAccessException e) { System.out.println(e); } catch (InvocationTargetException e) { System.out.println(e); } return result; }

29 29 Doing the same in Smalltalk meth ← #,. ^'Hello ' perform: meth with: 'everybody.'

30 30 Finding an object’s class Simply send it the message class Example: t ← Test new. ^t class Result: Test

31 31 Finding out if an object responds to a message Send respondsTo: to an object or canUnderstand: to a class. E.g. o ← 'hello'. ^o respondsTo: #first Collection canUnderstand: #size

32 32 Implementation of canUnderstand: canUnderstand: selector "Answer whether the receiver can respond to the message whose selector is the argument. The selector can be in the method dictionary of the receiver's class or any of its superclasses." (self includesSelector: selector) ifTrue: [^true]. superclass == nil ifTrue: [^false]. ^superclass canUnderstand: selector (Implemented in class Behaviour)

33 33 Finding all messages to which it responds Collection allSelectors Returns a Set of Symbols: Set (rootStubInImageSegment: hash copyAddedStateFrom: propertyList anyOne cCode: hashMappedBy: caseOf:otherwise: wantsSteps truncated ifNil:ifNotNil: asBag respondsTo: species detectMax: caseOf: initialDeepCopierSize range confirm: adaptToInteger:andSend: ~~ readDataFrom:size: windowActiveOnFirstClick * perform:with: finalize comeFullyUpOnReload: primitiveError: deepCopy...

34 34 Compiling a new method into a class Suppose that we have a class Test. Then evaluating: Test compile: 'double: aNumber ^aNumber * 2’ creates a new method for Test on the fly! So now we can do: Test new double: 42 and get the result 84.

35 35 Individual object behaviour Consider the following class definition: Object subclass: #Test instanceVariableNames: 'meth ' classVariableNames: '' poolDictionaries: '' category: 'Kernel-Objects' Instance methods: setSpecialMethod: aBlock meth ← aBlock specialMethod: aValue ^meth value: aValue

36 36 Indiv. object behaviour (ctd.) Then can create objects that behave differently. E.g. t1 ← Test new. t1 setSpecialMethod: [:i | i * 2]. t2 ← Test new. t2 setSpecialMethod: [:i| i - 1]. ^Array with: (t1 specialMethod: 42) with: (t2 specialMethod: 42) Result is: (84 41 )


Download ppt "1 Advanced Object Oriented Systems (CM0318) Lecture 8 (Last updated 15th February 2002)"

Similar presentations


Ads by Google