>> curry := [:query| ^[:a :b| (a perform: query) < (b perform:
>>query)]] >> I get a weird error: "Cannot return a Block closure to expired >>context >> or across processes". >I think your problem here is the carret "^". This tells ST to >return >from the method (context) in which the block was used. If you >assign the >block to a var and send it #value: later on the block get's >executed in >a BlockContext. And a block context cannot return from a >method .... Yes, I gues you're right, my main problem is that I'm not sure when I should include a caret inside a block. Can you give any pointers to this isssue? O:-) Thanks |
"Fernando" <[hidden email]> wrote:
... > Yes, I gues you're right, my main problem is that I'm not sure when I > should include a caret inside a block. Can you give any pointers to > this isssue? O:-) Very simple: the caret returns from the method invocation in which the block was created, if that method invocation has not been returned from yet. Cheers, Hans-Martin |
>Very simple: the caret returns from the method >invocation in which
the >block was created, if that method invocation has not >been returned from yet. Thank you, I though it exited the block. However, this sounds a bit drastic. What if I only want to prematurely exit the block, not the method where it was defined? Thanks. |
Fernando wrote:
> Thank you, I though it exited the block. However, this sounds a bit > drastic. What if I only want to prematurely exit the block, not the > method where it was defined? Short answer - you can't. There is no such thing as a block return. A block is allways executed completely and the result of the last expression is returned. You might work around this issue like this: [ :return | return notNil ifTrue: [ "some code" "just set return to a value to break out of the block and return"]. return notNil ifTrue: [ "some code" ]. return notNil ifTrue: [ "some code" ]. return notNil ifTrue: [ "some code" ]. return] CU, Udo |
In reply to this post by Fernando Rodríguez
Fernando wrote:
> What if I only want to prematurely exit the block, not the > method where it was defined? You can't. And that's really then end of the story, but just for interest.... Actually there are a few "clever" methods for doing this, but I wouldn't normally consider them for use in "real" code. Here's one of them: BlockClosure>>repeatWithExit ^ [self value: [:result | ^ result]] repeat. which can be used like: i := 0. [:exitWith | i > 10 ifTrue: [exitWith value: true]. i := i + 1] repeatWithExit. (And you can define #valueWithExit similarly) I wouldn't mention this except that your 'currying' example shows that you enjoy mind-benders ;-) Another way, even scairier, is to do stack introspection. (this, Dolphin specific, inplementation was suggested by Blair a few years ago -- so blame him, not me ;-): BlockClosure class>>returnFromCurrentWith: anObject Processor activeProcess topFrame sender return: anObject. which can be used like: [| i | i := 0. [i := i + 1. i > 10 ifTrue: [BlockClosure returnFromCurrentWith: true]] repeat. ] value. HTH ;-) -- chris |
In reply to this post by Fernando Rodríguez
Fernando wrote:
>>Very simple: the caret returns from the method >invocation in which > > the > >>block was created, if that method invocation has not >been returned > > from yet. > > Thank you, I though it exited the block. However, this sounds a bit > drastic. What if I only want to prematurely exit the block, not the > method where it was defined? You will need to implement an additional control structure. For a well-known idiom to implement a local return see http://lists.squeakfoundation.org/pipermail/squeak-dev/2000-July/000132.html Enjoy! Reinout ------- |
Reinout Heeck wrote:
> You will need to implement an additional control structure. > > For a well-known idiom to implement a local return see > > http://lists.squeakfoundation.org/pipermail/squeak-dev/2000-July/000132.html I didn't know this one .... one more thing from the "bag of tricks" category :-) CU, Udo |
In reply to this post by Fernando Rodríguez
"Fernando" <[hidden email]> wrote:
> >Very simple: the caret returns from the method >invocation in which > the > >block was created, if that method invocation has not >been returned > from yet. > > Thank you, I though it exited the block. However, this sounds a bit > drastic. What if I only want to prematurely exit the block, not the > method where it was defined? Others already wrote that it is not possible, and there is a reason for it, too: It would invite you to write needlessly complicated block structures :-) When you really need to have complicated control flow including early return within a block, it's very likely that this block should become a method instead. There are some things in Smalltalk which at first glance seem to be deficiencies, but once you think about them, they become hints by the system that you're doing something slightly wrong (of course, there are a few *real* deficiencies in Smalltalk, too...) Cheers, Hans-Martin |
Free forum by Nabble | Edit this page |