Part of Project Zurgle
This is a modified version of the previously released TwoModeButtonMorph that complies to the specification outlined in the WindowFrames paper.
As such, some of the protocols and structures have changed. There are two examples:
TwoModeButtonMorph example
Clicking the button opens a browser window in the demo. This code expects the file 'close.bmp' to be in the current Squeak directory for the demonstration.
and:
TwoModeButtonMorph example1
Clicking the button opens a browser window in the demo. This code uses a renderCode block to draw the button, rather than have images associated with it.
At this point, I'm thinking that I will not be releasing code to the list until I'm quite a bit further along in an attempt to keep list traffic down. Instead, I'll start gathering it and placing it on a web page, and post when I make significant changes. I post this changeset because I posted a previous version in the past.
This code was constructed in Squeak version 3.1a-4173
Jim
"Dance like it hurts. Love like you need money" -- Dogbert
How to reproduce (Squeak 3.1a-4347 with Squeak-3D or SqM):
Open a work space. Type "3 + 4" . Select it. 'Debug it'.
Keep 'SEND'ing until :
' ifFalse: [thisContext sender release]. ' "CRASH"
OK, here is the rest of the subject line ... when 'debug it'ed ;-)
Cheers,
PhiHo.
Hi,
This still happens with 3.2Alpha4418.
' ifFalse: [thisContext sender release]. ' is in Process>>terminate.
Where should I put a 'self halt.' to debug this problem ?
I tried to put 'self halt.' at the beginning of Process>>terminate, as soon as the change is accepted, I get a bunch of 'Halt' walkbacks one on top of the others.
All I can do with these is to move the top to reveal the one beneath.
How do I suppose to debug this ? Is it reproducible anywhere or it's just me and my machine ?
Thanks for your help.
Cheers.
PhiHo.
Process>>terminate "Stop the process that the receiver represents forever."
| context | Processor activeProcess == self ifTrue: [thisContext unwindTo: nil. thisContext sender == nil ifFalse: [thisContext sender release]. "Crash here!" thisContext removeSelf suspend] ifFalse: [myList == nil ifFalse: [myList remove: self ifAbsent: []. myList _ nil]. context _ suspendedContext. suspendedContext _ nil. context == nil ifFalse: [context unwindTo: nil]. (context ~~ nil and: [context sender ~~ nil]) ifTrue: [context sender release]]
----- Original Message ----- From: "PhiHo Hoang" phiho.hoang@home.com To: squeak-dev@lists.squeakfoundation.org Sent: Friday, September 28, 2001 7:32 PM Subject: [BUG] '3 + 4' crashes Squeak ...
How to reproduce (Squeak 3.1a-4347 with Squeak-3D or SqM):
Open a work space. Type "3 + 4" . Select it. 'Debug it'. Keep 'SEND'ing until : ' ifFalse: [thisContext sender release]. ' "CRASH"
OK, here is the rest of the subject line ... when 'debug it'ed ;-)
Cheers, PhiHo.
On Wednesday 03 October 2001 09:55 pm, PhiHo Hoang wrote:
This still happens with 3.2Alpha4418.
How do I suppose to debug this ? Is it reproducible anywhere or it's
just me and my machine ?
thisContext sender == nil ifFalse: [thisContext sender release]. "Crash here!"
On my machine, the current process goes away and becomes unresponsive, but I can get it back with alt-.
Hi Ned,
On my machine, the current process goes away and becomes unresponsive,
Thanks for your your confirmation
but I can get it back with alt-.
and tips. I forgot about that trick. Now it's "business as usual" after that fabulous 'alt-.'
Just wondering what's Squeak is busy doing ?
BTW, is it a Windows or *nix machine ?
As usual, you are such a help. I appreciate it.
Cheers,
PhiHo.
----- Original Message ----- From: "Ned Konz" ned@bike-nomad.com To: squeak-dev@lists.squeakfoundation.org Sent: Thursday, October 04, 2001 1:31 PM Subject: Re: [BUG] '3 + 4' crashes Squeak ...
On Wednesday 03 October 2001 09:55 pm, PhiHo Hoang wrote:
This still happens with 3.2Alpha4418.
How do I suppose to debug this ? Is it reproducible anywhere or it's
just me and my machine ?
thisContext sender == nil ifFalse: [thisContext sender release]. "Crash here!"
On my machine, the current process goes away and becomes unresponsive, but
I
can get it back with alt-.
-- Ned Konz currently: Stanwood, WA email: ned@bike-nomad.com homepage: http://bike-nomad.com
On Thursday 04 October 2001 05:40 pm, PhiHo Hoang wrote:
Just wondering what's Squeak is busy doing ?
Nothing special; I suspect that you killed off its UI task... hitting the interrupt (alt-.) key makes a new UI task.
BTW, is it a Windows or *nix machine ?
Mine is a Linux box, though I've been known to run Win2K in VMware under Linux for testing.
Ned Konz wrote:
Just wondering what's Squeak is busy doing ?
Nothing special; I suspect that you killed off its UI task...
I did nothing of this sort that I am aware of. No visible UI part disappeared in the whole scenario from the time I opened a workspace and typed in '3 + 4' until the 'alt-.' was needed. Did you do it ?
BTW, is it a Windows or *nix machine ?
Mine is a Linux box, though I've been known to run Win2K in VMware under Linux for testing.
That's cool. I must try this sometime, only the other way around ;-)
Cheers,
PhiHo.
PhiHo Hoang wrote:
Hi,
This still happens with 3.2Alpha4418. ' ifFalse: [thisContext sender release]. ' is in Process>>terminate. Where should I put a 'self halt.' to debug this problem ? I tried to put 'self halt.' at the beginning of Process>>terminate, as
soon as the change is accepted, I get a bunch of 'Halt' walkbacks one on top of the others.
You could try the #doOnlyOnce: trick that Randal Schwartz mentioned last week.
Insert this instead into the place where you were putting your halt:
self doOnlyOnce: [self halt].
See ProtoObject>>doOnlyOnce: for more details. (By the way, it seems like this method doesn't really need to be all the way up in ProtoObject, since it's just a utility method which doesn't refer to self. Maybe Object would suffice?)
- Doug Way dway@riskmetrics.com
"Doug" == Doug Way dway@riskmetrics.com writes:
Doug> Insert this instead into the place where you were putting your halt:
Doug> self doOnlyOnce: [self halt].
Doug> See ProtoObject>>doOnlyOnce: for more details. (By the way, it Doug> seems like this method doesn't really need to be all the way up Doug> in ProtoObject, since it's just a utility method which doesn't Doug> refer to self. Maybe Object would suffice?)
How would you debug a non-Object object then? you couldn't say "self doOnlyOnce: ...".
It needs to be at the top of the foodchain to be useful for everything.
"Randal L. Schwartz" wrote:
"Doug" == Doug Way dway@riskmetrics.com writes:
Doug> Insert this instead into the place where you were putting your halt:
Doug> self doOnlyOnce: [self halt].
Doug> See ProtoObject>>doOnlyOnce: for more details. (By the way, it Doug> seems like this method doesn't really need to be all the way up Doug> in ProtoObject, since it's just a utility method which doesn't Doug> refer to self. Maybe Object would suffice?)
How would you debug a non-Object object then? you couldn't say "self doOnlyOnce: ...".
It needs to be at the top of the foodchain to be useful for everything.
Well, you could do something like "1 doOnlyOnce: [1 halt]" to set a one-time halt in a non-Object.
#halt currently isn't in ProtoObject, so you won't be able to do a "self halt" there anyway. It kind of seems like the #doOnlyOnce:/#rearmOneShot code is related to #halt/etc and maybe belongs with that stuff in Object. Although I suppose one might have a reason to use doOnlyOnce: without doing a halt.
ProtoObject is pretty lean & mean with only 19 methods, so you don't want to add any more than is absolutely necessary there...
- Doug Way dway@riskmetrics.com
"Doug" == Doug Way dway@riskmetrics.com writes:
Doug> Well, you could do something like "1 doOnlyOnce: [1 halt]" to Doug> set a one-time halt in a non-Object.
Doug> #halt currently isn't in ProtoObject, so you won't be able to do Doug> a "self halt" there anyway. It kind of seems like the Doug> #doOnlyOnce:/#rearmOneShot code is related to #halt/etc and Doug> maybe belongs with that stuff in Object. Although I suppose one Doug> might have a reason to use doOnlyOnce: without doing a halt.
Doug> ProtoObject is pretty lean & mean with only 19 methods, so you Doug> don't want to add any more than is absolutely necessary there...
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"
Then it would be useful even in proto objects, although we again run into the self-halt issue. :)
Or even just teach SystemDictionary to do that by moving the code in ProtoObject to SystemDictionary instance methods.
(Smalltalk) >> armOnce self at: #armOnce put: true (Smalltalk) >> doOnce: aBlock (self at: #armOnce) ifTrue: [self at: #armOnce put: false. aBlock value]
I know. "Changesets welcome" :)
"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@riskmetrics.com
On Thursday 04 October 2001 05:06 pm, Doug Way wrote:
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.
And, of course, the doOnlyOnce should have a flag per block, rather than a global flag, so you can have more than one of them.
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@riskmetrics.com To: squeak-dev@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@riskmetrics.com
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@riskmetrics.com To: squeak-dev@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@riskmetrics.com
'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]. ! !
'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!
Hi,
Thanks for the change sets. I will report back.
Cheers,
PhiHo.
----- Original Message ----- From: "Torge Husfeldt" jean-jacques.gelee@gmx.de To: squeak-dev@lists.squeakfoundation.org Sent: Friday, October 05, 2001 1:29 PM Subject: Re: #doOnlyOnce (was Re: [BUG] '3 + 4' crashes Squeak ...)
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@riskmetrics.com To: squeak-dev@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@riskmetrics.com
---------------------------------------------------------------------------- ----
'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]. ! !
---------------------------------------------------------------------------- ----
'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!
Hi,
Why not put it in SystemDictionary, Then it would be a doOnlyOnceForThisNamespace (If this is where namespaces live, but it sounds really natural to me?!). Since it doesn't refer to self you could move it anywhere. And in Namespace it could refer to self. So you could write: Smalltalk doOnlyOnce:[aBlock] Or: ThisNamespace doOnlyOnce:[aBlock]
You don't need this to be defined in ProtoObject in order to debug an instance of ProtoObject (or am i missing something?).
"Doug" == Doug Way dway@riskmetrics.com writes:
Doug> Insert this instead into the place where you were putting your halt:
Doug> self doOnlyOnce: [self halt].
Doug> See ProtoObject>>doOnlyOnce: for more details. (By the way, it Doug> seems like this method doesn't really need to be all the way up Doug> in ProtoObject, since it's just a utility method which doesn't Doug> refer to self. Maybe Object would suffice?)
How would you debug a non-Object object then? you couldn't say "self doOnlyOnce: ...".
It needs to be at the top of the foodchain to be useful for everything.
-- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 merlyn@stonehenge.com URL:http://www.stonehenge.com/merlyn/ Perl/Unix/security consulting, Technical writing, Comedy, etc. etc. See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Hi Doug,
Thanks for the tips.
You could try the #doOnlyOnce: trick that Randal Schwartz mentioned last
week.
and thanks to you too, Randal.
Insert this instead into the place where you were putting your halt:
self doOnlyOnce: [self halt].
I overlooked this one. I will try it out and let you know.
Cheers,
PhiHo.
----- Original Message ----- From: "Doug Way" dway@riskmetrics.com To: squeak-dev@lists.squeakfoundation.org; "PhiHo Hoang" phiho.hoang@home.com Sent: Thursday, October 04, 2001 3:14 PM Subject: Re: [BUG] '3 + 4' crashes Squeak ...
PhiHo Hoang wrote:
Hi,
This still happens with 3.2Alpha4418. ' ifFalse: [thisContext sender release]. ' is in Process>>terminate. Where should I put a 'self halt.' to debug this problem ? I tried to put 'self halt.' at the beginning of Process>>terminate,
as
soon as the change is accepted, I get a bunch of 'Halt' walkbacks one on
top
of the others.
You could try the #doOnlyOnce: trick that Randal Schwartz mentioned last
week.
Insert this instead into the place where you were putting your halt:
self doOnlyOnce: [self halt].
See ProtoObject>>doOnlyOnce: for more details. (By the way, it seems like
this method doesn't really need to be all the way up in ProtoObject, since it's just a utility method which doesn't refer to self. Maybe Object would suffice?)
- Doug Way dway@riskmetrics.com
squeak-dev@lists.squeakfoundation.org