[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