For the people following I added a test to show the homeContext of a block
| homeContext b1 |
homeContext := thisContext.
b1 := [| b2 |
self assert: thisContext closure == b1.
self assert: b1 outerContext == homeContext.
self assert: b1 home = homeContext.
b2 := [self assert: thisContext closure == b2.
self assert: b2 outerContext closure outerContext ==
homeContext].
self assert: b2 home = homeContext.
b2 value].
b1 value
>
>
> On Tue, Jul 23, 2013 at 2:02 AM, Stéphane Ducasse <[email protected]>
> wrote:
> thanks!
> It makes a lot of sense.
> I will play with another example because I want to really understand the
> outerContext of closure vs the home context.
>
> The outerContext is a link in the static chain. Each block is created inside
> some context. This is the block's outerContext. If the block is not nested
> then the outerCOntext will also be the home context But if the block is
> nested inside another block activation, then the outerContext refers to that
> block activation, and the block activation's block's outerContext is the home
> context. So there are as many outerContext steps as there are nesting levels.
>
> | homeContext b1 |
> homeContext := thisContext.
> b1 := [| b2 |
> self assert: thisContext closure == b1.
> self assert: b1 outerContext == homeContext.
> b2 := [self assert: thisContext closure == b2.
> self assert: b2 outerContext closure outerContext ==
> homeContext].
> b2 value].
> b1 value
>
> Ignore the "bN appears to be undefined at this point" and evaluate the above.
> No assert fails.
>
> Draw a picture.
>
>
> Stef
>
> On Jul 23, 2013, at 6:58 AM, Clément Bera <[email protected]> wrote:
>
>> This is because of compilation optimization.
>>
>> 2013/7/22 Stéphane Ducasse <[email protected]>
>> Hi
>>
>> when I execute the following
>>
>> first
>> "Bexp new first"
>> | temp |
>> temp := 2.
>> [ temp.
>> thisContext inspect.] value.
>> ^ temp
>>
>> tmp in the inspector is nil and does not hold 2 and I was wondering why.
>> I thought that thisContext was returning the blockContext
>> In the outercontext of thisContext blockClosure, tmp is also nil.
>>
>>
>> This is because here 'temp.' is evaluated for effect (the value is not
>> stored anywhere) and it has no side effect (reading a variable cannot lead
>> to a modification of state of another object). So the compiler removes it.
>> As it is removed, it is the same as if it was not in the block. So the block
>> cannot access temp. Now write 'temp:= #foo' or 'temp foo' you will get it.
>>
>> first
>> "Bexp new first"
>> | temp |
>> temp := 2.
>> [ temp.
>> temp traceCr.
>> thisContext inspect.] value.
>> ^ temp
>>
>> output 2 on the transcript.
>>
>> In this case 'temp.' is still removed, but the value of temp still need to
>> be copied in the block for ' temp traceCr.'.'temp traceCr' is also evaluated
>> for effect, but has the side effect to output the transcript, so the
>> compiler cannot remove it.
>>
>> Basically the is very few things that the compiler removes, and one of them
>> is variable read for effect, because you are sure it cannot lead to any
>> issue.
>>
>> Stef
>>
>>
>
>
>
>
> --
> best,
> Eliot