[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 17:02:47 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 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?

>
> Levente
>
>>
>>
>>>
>>> Levente
>>>
>>>




-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list