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

Levente Uzonyi leves at elte.hu
Wed Mar 3 16:07:39 UTC 2010


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.


Levente

>
>
>>
>> Levente
>>
>>
>>> Cheers,
>>> Balázs & Levente
>>>
>>>
>>>>
>>>> *yay
>>>> Henry*
>>>> *
>>>
>>>
>>>
>>>
>>
>>
>>
>> --
>> Best regards,
>> Igor Stasenko AKA sig.
>>
>> _______________________________________________
>> Pharo-project mailing list
>> Pharo-project at lists.gforge.inria.fr
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>>
>>
>>
>
>
>
> -- 
> Best regards,
> Igor Stasenko AKA sig.
>
>


More information about the Squeak-dev mailing list