[Pharo-project] [squeak-dev] #ensure: issues (was: Re: Pharo by Example vol 2: new chapter available)

Igor Stasenko siguctua at gmail.com
Wed Mar 3 21:50:27 UTC 2010


2010/3/3 Levente Uzonyi <leves at elte.hu>:
> On Wed, 3 Mar 2010, Igor Stasenko wrote:
>
>> 2010/3/3 Levente Uzonyi <leves at elte.hu>:
>>>
>>> On Wed, 3 Mar 2010, Igor Stasenko wrote:
>>>
>>>> 2010/3/3 Levente Uzonyi <leves at elte.hu>:
>>>>>
>>>>> On Tue, 2 Mar 2010, Igor Stasenko wrote:
>>>>>
>>>>>> 2010/3/2 Levente Uzonyi <leves at elte.hu>:
>>>>>> On Tue, 2 Mar 2010, Henrik Sperre Johansen wrote:
>>>>>>
>>>>>>>
>>>>>>>>> PS. For the not-so-faint-of-heart, open a Transcript and try
>>>>>>>>> evaluating:
>>>>>>>>> |proc|
>>>>>>>>> proc := [[Transcript show: 'Start!'. ] ensure: [Transcript show:
>>>>>>>>> 'Finish!' Processor yield.]] newProcess.
>>>>>>>>> proc resume.
>>>>>>>>> Processor yield.
>>>>>>>>> proc suspend.
>>>>>>>>> proc terminate.
>>>>>>>>
>>>>>>>> Why don't we get it printing?
>>>>>>>
>>>>>>> Forgot a . there, supposed to be
>>>>>>>
>>>>>>> |proc|
>>>>>>> proc := [[Transcript show: 'Start!'. ] ensure: [Transcript show:
>>>>>>> 'Finish!'. Processor yield.]] newProcess.
>>>>>>> proc resume.
>>>>>>> Processor yield.
>>>>>>> proc suspend.
>>>>>>> proc terminate.
>>>>>>>
>>>>>>> on my machine it prints:
>>>>>>> *Start!Start!Finish!
>>>>>>
>>>>>> The problem occurs because Transcript >> #endEntry (sent from #show:)
>>>>>> takes a while to execute, so the process (proc) prints 'Start!', but
>>>>>> it gets terminated before execution reaches #resetContents (#reset in
>>>>>> Squeak). So 'Start!' is still in the stream. Then our process executes
>>>>>> the
>>>>>> #ensure: block and it prints 'Start!' and 'Finish!' too.
>>>>>>
>>>>>> There's worse problem with #ensure: and #terminate is that, a process
>>>>>> executing an #ensure: block can be terminated. If you evaluate this
>>>>>> code:
>>>>>>
>>>>>> | process stage1 stage2 stage3 counter |
>>>>>> stage1 := stage2 := stage3 := false.
>>>>>> counter := 0.
>>>>>> process := [
>>>>>>        [ stage1 := true ] ensure: [
>>>>>>                stage2 := true.
>>>>>>                1000000 timesRepeat: [ counter := counter + 1 ].
>>>>>>                stage3 := true ] ] newProcess.
>>>>>> process resume.
>>>>>> Processor yield.
>>>>>> process suspend.
>>>>>> process terminate.
>>>>>> 1000 milliSeconds asDelay wait.
>>>>>> { stage1. stage2. stage3. counter } explore
>>>>>>
>>>>>> you will find that stage1 and stage2 is reached as expected, but
>>>>>> stage3
>>>>>> is
>>>>>> not and counter is less than 1000000. That's because the forked
>>>>>> process
>>>>>> started evaluating the #ensure: block, but it was terminated by our
>>>>>> process.
>>>>>>
>>>>>> Is this the expected behavior when sending #terminate to a process
>>>>>> which
>>>>>> is
>>>>>> evaluating an #ensure: block?
>>>>>>
>>>>>>
>>>>> What you think is expected behavior here:
>>>>>
>>>>> a) process termination should start (be triggered) only when process
>>>>> is outside of any #ensure: closure?
>>>>> b) #ensure: block should always run to the end, despite anything?
>>>>>
>>>>> Since you can't predict, what code will run inside ensure block, the
>>>>> only guarantee that you having is actually
>>>>> that your process will always enters such blocks during the normal
>>>>> flow, or exception handling. But there is no guarantees that it will
>>>>> be able to run the code inside it, when you terminating it.
>>>>>
>>>>>
>>>>> I'd expect it to be evaluated no matter what happens.
>>>>>
>>>> even this one?
>>>> [self boom ] ensure: [ self halt. Transcript show: 'boom']
>>>
>>> Yes.
>>>
>> so, even if you click 'abandon' in debugger popup, its still should
>> print 'boom' in transcript?
>
> I didn't say that. I said evaluate it the same way as normal code.

Please define, what is 'normal' code. If you maybe know, exceptions
and stack unwinding implemented in smalltalk, there's no any 'magic'
and this code interpreted by VM as any other code, which makes it as
'normal' as any other one.

> If you evaluate this code:
>
> self halt. Transcript show: 'boom'.
>
> and press abandon, then Transcript show: 'boom' will not be executed.
>

i don't get it. Just before that, you said: ' I'd expect it to be
evaluated no matter what happens.' ?
But now you saying that it may not be executed in some conditions
(when user pressing abandon button, causing process to be terminated).

>
> Levente
>
>>
>>>
>>> Levente
>>>
>>>>
>>>>
>>>>>
>>>>> Levente
>>>>>
>>>>>
>>
>>
>>
>>
>> --
>> Best regards,
>> Igor Stasenko AKA sig.
>>
>
>
>
>



-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list