[squeak-dev] Block closure and scope problem
Rodney Polkinghorne
rodneyp at physics.uq.edu.au
Fri May 27 06:53:22 UTC 2011
Hi all
I'm trying to build a morph whose co-ordinates are set by blocks. My
current attempt is below.
When I did "(LiteralDot locus: 100 at 100) openInWorld" in a workspace,
the call of locusGetter in computeBounds raised a "Block can not
return" error. The debugger and inspector present a trail of
BlockContexts and MessageContexts. This failed to enlighten me.
I haven't a clue what self and super refer to in a closure, but I
thought I knew how lexical variables worked. Apparently not. Would
anyone care to explain, or point me to an explanation?
Rodney
Change set follows:
'From Squeak4.2 of 4 February 2011 [latest update: #10966] on 27 May
2011 at 4:40:43 pm'!
Smalltalk renameClassNamed: #StickMorph as: #DotMorph!
Morph subclass: #DotMorph
instanceVariableNames: 'locusGetter locusSetter'
classVariableNames: ''
poolDictionaries: ''
category: 'UserObjects'!
!DotMorph commentStamp: 'resp 5/27/2011 16:27' prior: 0!
I am a dot 4 pixels in diameter. My center is computed by a block,
which is stored in my instance variable locusGetter. Subclasses
should initialize this before I am drawn.!
Smalltalk renameClassNamed: #ToyStick as: #LiteralDot!
DotMorph subclass: #LiteralDot
instanceVariableNames: 'locus'
classVariableNames: ''
poolDictionaries: ''
category: 'UserObjects'!
!LiteralDot commentStamp: 'resp 5/27/2011 16:35' prior: 0!
I am a dot, whose position is stored explicitly in my instance
variable locus. My constructor sends me an initializeBlocks message.
This sets my locusGetter to a block that is supposed to return the
value of that variable. It actually raises a "cannot return" error.!
!DotMorph methodsFor: 'as yet unclassified' stamp: 'resp 5/27/2011 16:28'!
drawOn: aCanvas
self computeBounds.
aCanvas fillOval: self bounds color: Color black.! !
!DotMorph methodsFor: 'private' stamp: 'resp 5/27/2011 16:28'!
computeBounds
bounds := Rectangle center: locusGetter value extent: 4! !
!DotMorph methodsFor: 'private' stamp: 'resp 5/27/2011 16:28'!
locusGetter: aBlock
locusGetter := aBlock.
! !
!LiteralDot methodsFor: 'accessing' stamp: 'resp 5/27/2011 16:09'!
locus: aPoint
locus := aPoint! !
!LiteralDot methodsFor: 'as yet unclassified' stamp: 'resp 5/27/2011 16:10'!
initializeBlocks
"This must be an instance method for the blocks to close over the
right environment."
self locusGetter: [ ^ locus ]; locusSetter: [ :p | locus := p ]! !
!LiteralDot class methodsFor: 'as yet unclassified' stamp: 'resp
5/27/2011 16:08'!
locus: aPoint
^ (super new)
initializeBlocks;
locus: aPoint
! !
!LiteralDot reorganize!
('accessing' locus:)
('as yet unclassified' initializeBlocks)
!
DotMorph removeSelector: #locusSetter:!
!DotMorph reorganize!
('as yet unclassified' drawOn:)
('private' computeBounds locusGetter:)
!
More information about the Squeak-dev
mailing list
|