[ENH] BlockContext>>doOnlyOnce (Version 3: major bug fixed)

Torge Husfeldt jean-jacques.gelee at gmx.de
Tue Apr 2 09:05:29 UTC 2002


Hi List,
Doug just pointed out a major bug in my implementation of #doOnlyOnce.
In fact the version i posted was a really complicated version of #value.
Here comes the bug fix with the proper (i hope) subject line and some
example code.
I changed the logic for logging the oneShots that are already fired from
BlockContext instances to MethodContexts (their homeContext). This means (1)
that every method can have only one oneShot (2) every oneShot gets rearmed
automatically on recompile.
Make sure to clean out the OneShotsFired dictionary by calling BlockContext
rearmAllOneShots if you use this faeture heavily.

Squeak on,
Torge
-------------- next part --------------
'From Squeak3.2alpha of 1 November 2001 [latest update: #4646] on 2 April 2002 at 10:46:53 am'!
"Change Set:		DoOnlyOnceRefD-th
Date:			2 April 2002
Author:			Torge Husfeldt
Thanks:			Doug Way
This is a rework of the Oct 2001 version of my oneShot changeset.
Do not use the earlier version because it doesn't work properly (at least not with Squeak3.2a)
The simple version of the same date should be OK.
Chages in version 3 of 2 April 2002:
Changed the logging from BlockContext to their homeContext.
BlockContext were created too often.
Original preamble:
"
ProtoObject confirmRemovalOf: #doOnlyOnce.
ProtoObject confirmRemovalOf: #rearmOneShot.
"Moves the doOnlyOnce functionality
>from ProtoObject to BlockContext
The Syntax for a one-shot changed by this from:
self doOnlyOnce:[self halt]
to:
[anObject halt] doOnlyOnce

This has the following positive consequences:
ProtoObject gets a little lighter in methods.
The one-shot mechanism now works with more granularity. Every one-shot Block is executed once no matter if the one-shot has already been used. Every one-shot Block can be rearmed individually."!

ContextPart variableSubclass: #BlockContext
	instanceVariableNames: 'nargs startpc home '
	classVariableNames: 'OneShotsFired '
	poolDictionaries: ''
	category: 'Kernel-Methods'!

!BlockContext methodsFor: 'evaluating' stamp: 'th 4/2/2002 10:26'!
doOnlyOnce
	"If the 'one-shot' mechanism is armed, evaluate self once and disarm the one-shot mechanism.
	To rearm the mechanism, evaluate  'BlockContext rearmOneShotsFor: Class->#selector' manually.
	If you have the Block handy you can also do 'aBlock rearmOneShot'"	
	^(self class doOneShot: self)
		ifTrue:[self value]
		ifFalse:[nil]

	! !

!BlockContext methodsFor: 'evaluating' stamp: 'th 10/5/2001 19:18'!
rearmOneShot
	"Call this manually to arm the one-shot mechanism; use the mechanism in code by calling
		<a block> doOnlyOnce"
	self class rearmOneShot: self! !


!BlockContext class methodsFor: 'as yet unclassified' stamp: 'th 4/2/2002 10:29'!
doOneShot: aBlock
	| key oneShotsDict granted |
	key _ aBlock home.
	oneShotsDict _ self oneShotsFired.
	granted _ (oneShotsDict at: key ifAbsent:[false]) not.
	oneShotsDict at: key put: true.
	^granted! !

!BlockContext class methodsFor: 'as yet unclassified' stamp: 'th 10/5/2001 19:14'!
oneShotsFired
	"utility method for the one-shot mechanism; lazily initialized (see #doOnlyOnce on instance side)"
	^OneShotsFired ifNil:[OneShotsFired _ Dictionary new]! !

!BlockContext class methodsFor: 'as yet unclassified' stamp: 'th 10/5/2001 19:13'!
rearmAllOneShots
	"utility function for the one-shot mechanism (see #doOnlyOnce on instance side)"
	OneShotsFired _ nil.! !

!BlockContext class methodsFor: 'as yet unclassified' stamp: 'th 4/2/2002 10:28'!
rearmOneShot: aBlock
	"utility function for the one-shot mechanism. Reams the mechanis for aBlock"
	self oneShotsFired at: aBlock home put: false! !

!BlockContext class methodsFor: 'as yet unclassified' stamp: 'th 4/2/2002 10:30'!
rearmOneShotsInMethod: aClassSelectorPair
	"utility function for the one-shot mechanism. Reams the mechanism for all blocks in a method.
	aClassSelctorPair is really an association. The key must be the implementor class. The value must be a symbol(selector)"
	self oneShotsFired at: aClassSelectorPair put: false
! !

ProtoObject removeSelector: #doOnlyOnce:!
ProtoObject removeSelector: #rearmOneShot!


More information about the Squeak-dev mailing list