I'm playing around with BookMorphs -- actually, I'm trying to get my ECOOP presentation into a book, just to see if I can. On this journey, I have encounterd an error that I just plain don't understand. That is: I don't understand the message that the debugger is sending me!
After reading in (in my case, right now, zero pages), the image reading code writes out the bookMorph. I get the same problem if I just write out a bookMorph from the menu. I see a progress dialog 'please wait while the objects are counted', and then get a MNU. Here is the (top of the) walkback:
29 April 2001 6:18:04 pm MessageNotUnderstood: xxxInstVarAt:
VM: Mac OS - nil Image: Squeak3.1alpha [latest update: #'Squeak3.1alpha' of 12 April 2001 update 3910]
PasteUpMorph(Object)>>doesNotUnderstand: PasteUpMorph>>DoItwith: ReferenceStream(DataStream)>>writeInstance: ReferenceStream(DataStream)>>nextPut: [] in ReferenceStream(DataStream)>>nextPutAll: Array(SequenceableCollection)>>do: ...
What's weird here is that writeInstance -- code shown here ---
writeInstance: anObject "PRIVATE -- Write the contents of an arbitrary instance."
^ anObject storeDataOn: self
is sending "storeDataOn: self" to anObject, and anObject is "a PasteUpMorph<page>(2386)", the pasteUpMorph that is the top page in my book. So, far, so good. But the method that shows up in the next frame of the stack trace is "DoItWith". When I browse that frame with the debugger, what I see is the following method:
storeDataOn: aDataStream "Store myself on a DataStream. See also objectToStoreOnDataStream. must send 'aDataStream beginInstance:size:'" | cntInstVars |
cntInstVars _ self class instSize. "cntIndexedVars _ self basicSize." aDataStream beginInstance: self xxxClass size: cntInstVars "+ cntIndexedVars". 1 to: cntInstVars do: [:i | aDataStream nextPut: (self xxxInstVarAt: i)]. " 1 to: cntIndexedVars do: [:i | aDataStream nextPut: (self basicAt: i)] " This is not a method from PasteUpMorph at all. It's a method from ObjectOut, which is why it is reasonable for it to be sending xxxInstVarAt: to self. But self is my PastUpMorph, hence the MNU.
So, what's going on here? Perhaps my PasteUpMorph has become an ObjectOut and then become a PasteUpMorph again? If so, why is it trying to store itself on the disk? Was it reconstituted a bit too soon? Here be deep magic! All that I wanted to do was load some images ...
Here is the whole of SqueakDebug.log:
29 April 2001 6:18:04 pm MessageNotUnderstood: xxxInstVarAt:
VM: Mac OS - nil Image: Squeak3.1alpha [latest update: #'Squeak3.1alpha' of 12 April 2001 update 3910]
PasteUpMorph(Object)>>doesNotUnderstand: PasteUpMorph>>DoItwith: ReferenceStream(DataStream)>>writeInstance: ReferenceStream(DataStream)>>nextPut: [] in ReferenceStream(DataStream)>>nextPutAll: Array(SequenceableCollection)>>do: ReferenceStream(DataStream)>>nextPutAll: ReferenceStream(DataStream)>>writeArray: ReferenceStream(DataStream)>>nextPut: SmartRefStream>>instVarInfo: [] in SmartRefStream>>nextPut: ProgressInitiationException>>defaultAction ProgressInitiationException(Exception)>>pass [] in BlockContext>>valueUninterruptably ProgressInitiationException(Exception)>>handlerAction ProgressInitiationException(Exception)>>signal ProgressInitiationException>>display:at:from:to:during: ProgressInitiationException class>>display:at:from:to:during: String>>displayProgressAt:from:to:during: SmartRefStream>>nextPut: StandardFileStream(ReadWriteStream)>>fileOutClass:andObject: [] in BookMorph>>saveIndexOnURL BlockContext>>on:do: [] in BlockContext>>valueUninterruptably BlockContext>>on:do: [] in BlockContext>>valueUninterruptably BlockContext>>on:do: BlockContext>>valueUninterruptably BlockContext>>ensure: CursorWithMask(Cursor)>>showWhile: BookMorph>>saveIndexOnURL BookMorph>>saveAsNumberedURLs BookMorph>>savePagesOnURL BookMorph>>loadImagesIntoBook [] in MenuItemMorph>>invokeWithEvent: BlockContext>>on:do: [] in BlockContext>>valueUninterruptably BlockContext>>on:do: [] in BlockContext>>valueUninterruptably BlockContext>>on:do: BlockContext>>valueUninterruptably BlockContext>>ensure: CursorWithMask(Cursor)>>showWhile: MenuItemMorph>>invokeWithEvent: MenuItemMorph>>mouseUp: MenuItemMorph>>handleMouseUp: MouseButtonEvent>>sentTo: MenuItemMorph(Morph)>>handleEvent: MorphicEventDispatcher>>dispatchDefault:with: MorphicEventDispatcher>>dispatchEvent:with: MenuItemMorph(Morph)>>processEvent:using: MorphicEventDispatcher>>dispatchDefault:with: MorphicEventDispatcher>>dispatchEvent:with: MenuMorph(Morph)>>processEvent:using: MenuMorph(Morph)>>processEvent: MenuMorph>>handleFocusEvent: [] in HandMorph>>sendFocusEvent:to:clear: PasteUpMorph>>becomeActiveDuring: HandMorph>>sendFocusEvent:to:clear: HandMorph>>sendEvent:focus:clear: HandMorph>>sendMouseEvent: HandMorph>>handleEvent: HandMorph>>processEvents [] in WorldState>>doOneCycleNowFor: Array(SequenceableCollection)>>do: WorldState>>handsDo: WorldState>>doOneCycleNowFor: WorldState>>doOneCycleFor: PasteUpMorph>>doOneCycle [] in Project class>>spawnNewProcess [] in BlockContext>>newProcess
Andrew P. Black wrote:
This is not a method from PasteUpMorph at all. It's a method from ObjectOut, which is why it is reasonable for it to be sending xxxInstVarAt: to self. But self is my PastUpMorph, hence the MNU.
So, what's going on here? Perhaps my PasteUpMorph has become an ObjectOut and then become a PasteUpMorph again? If so, why is it trying to store itself on the disk? Was it reconstituted a bit too soon? Here be deep magic! All that I wanted to do was load some images ...
I think you have uncovered some of the dark magic in this code, where some things are not what they seem (I know it involves a trick application of the garbage collector as well), but an explanation would probably require a word from the author of the objects-to-disk functionality...
Henrik
squeak-dev@lists.squeakfoundation.org