#doOnlyOnce (was Re: [BUG] '3 + 4' crashes Squeak ...)

Torge Husfeldt jean-jacques.gelee at gmx.de
Fri Oct 5 17:29:27 UTC 2001


Changesets ready for testing.
the first is more lightweight. the second is the full monty

PhiHo Hoang wrote:
> 
> Hi Doug,
> 
> > [self halt] doOnlyOnce.
> 
>     This is neat, I like it. But is it sementically the same as:
> 
>     self doOnlyOnce: [self halt].
> 
>     If you have a change set, I volunteer to test it ;-)
> 
>     Cheers,
> 
>     PhiHo
> 
> ----- Original Message -----
> From: "Doug Way" <dway at riskmetrics.com>
> To: <squeak-dev at lists.squeakfoundation.org>
> Sent: Thursday, October 04, 2001 8:06 PM
> Subject: #doOnlyOnce (was Re: [BUG] '3 + 4' crashes Squeak ...)
> 
> >
> > "Randal L. Schwartz" wrote:
> > >
> > > In that case, what you really want is a DoOnlyOnce class subclassed
> > > from Object, as a singleton, with the protocol:
> > >
> > >         DoOnlyOnce arm "in a do-it"
> > >
> > >         ...
> > >
> > >         DoOnlyOnce once: [self halt] "in a method"
> >
> > Looking at this (and our earlier exchanges), and noticing that we're
> trying to find a place to hang a method which is always passed a block...
> now I'm thinking that the best way to handle it would be to add an instance
> method to BlockContext, so that the usage becomes simply:
> >
> > [self halt] doOnlyOnce.
> >
> > (Or, in keeping with other BlockContext methods, maybe #valueOnlyOnce.
> But somehow #doOnlyOnce seems better.)
> >
> > The #rearmOneShot method would become a class method for BlockContext.
> >
> > > ...
> > > I know.  "Changesets welcome" :)
> >
> > Yes.  Not that it would be hard to make this changeset, but I'd rather
> wait until the violent disagreement subsides first... :)
> >
> > - Doug Way
> >   dway at riskmetrics.com
> >
> >
-------------- next part --------------
'From Squeak3.0 of 4 February 2001 [latest update: #3552] on 5 October 2001 at 6:37:38 pm'!

!BlockContext methodsFor: 'evaluating' stamp: 'th 10/5/2001 18:18'!
doOnlyOnce
	Smalltalk
		at: #OneShotArmed
		ifAbsent:[
			Smalltalk at:#OneShotArmed put: false.
			self value].
	! !

-------------- next part --------------
'From Squeak3.0 of 4 February 2001 [latest update: #3552] on 5 October 2001 at 7:27:18 pm'!
"Change Set:		DoOnlyOnceRefD-th
Date:			5 October 2001
Author:			Torge Husfeldt
"
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 10/5/2001 19:27'!
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 oneShotsFired
		at: self
		ifAbsent:
			[| rclass selector |
			rclass _ self receiver class.
			selector _ rclass selectorAtMethod: self method setClass:[:c].
			self class oneShotsFired
				at: self
				put:(rclass -> selector).
			self value]
	! !

!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 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 10/5/2001 19:14'!
rearmOneShot: aBlock
	"utility function for the one-shot mechanism. Reams the mechanis for aBlock"
	OneShotsFired 
		ifNil:[^ self]
		ifNotNil:
			[OneShotsFired removeKey: aBlock ifAbsent:[]]! !

!BlockContext class methodsFor: 'as yet unclassified' stamp: 'th 10/5/2001 19:17'!
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)"
	OneShotsFired 
		ifNil:[^ self]
		ifNotNil:
			[OneShotsFired keysAndValuesRemove: 
				[:key :value | 
				value = aClassSelectorPair]]! !

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


More information about the Squeak-dev mailing list