A discussion in IRC prompted me to try several things.
In a nutshell, execute these two lines with two separate doits and you get an error. Select both lines and doit and you don't:
a := [^true]. a value.
I assume there is a valid reason for the difference in behavior, but it DOES remind one that workspace behavior isn't always the same as method behavior, even for something as simple as the above.
L.
On 3 March 2012 16:29, Lawson English lenglish5@cox.net wrote:
A discussion in IRC prompted me to try several things.
In a nutshell, execute these two lines with two separate doits and you get an error. Select both lines and doit and you don't:
a := [^true]. a value.
I assume there is a valid reason for the difference in behavior, but it DOES remind one that workspace behavior isn't always the same as method behavior, even for something as simple as the above.
Indeed. Given there's a non-local return in the block, the statement "return from the method context that invoked me" means something rather different in the two ways you run this.
In the second case, you'll have an UndefinedObject>>DoIt context (call it C1) running "a := [^true]". The ^ captures the home context - C1 - so that when the block returns, it will return from C1. Since "a value" then executes within C1's context, there's no problem.
But in the first case, C1 executes "a := [^ true]", finishes, and then pops off the call stack. When you select "a value", it too executes within an UndefinedObject>>DoIt context (call it C2). The block then executes and "^ true" tries to return... from C1. Only C1's now garbage.
In fact, within the debugger, go to the MethodContext>>cannotReturn: context, and explore "self home". You'll see that receiver = nil, indicating that it's not connected to a call stack. Compare that context with thisContext, and you'll see that thisContext receiver ~= nil.
frank
squeak-dev@lists.squeakfoundation.org