How do you realize a try-catch-finally idiom in smalltalk? I see there is on:do:
and ensure:
, but there isn't on:do:ensure:
. I must be missing something.

- 2,355
- 2
- 23
- 38
4 Answers
You could wrap the #on:do block in another block that has the #ensure: attached to it.

- 4,559
- 23
- 27
-
Ah indeed. I thought of it but somehow I thought it will execute the inner block twice, because both #on:do: and #ensure: send #value. – milan Oct 21 '11 at 08:20
-
1`#ensure:`'s send of `#value` will evaluate its contents, which will send `#on:do:` to its contents, which in turn will send `#value` to the innermost block, which will finally do something useful. In other words, the two `#value` sends are sent to different blocks. – Frank Shearar Oct 21 '11 at 11:21
If you really need it, you can add a protocol to BlockClosure:
#on: anErrorOrSet do: errorBlock ensure: finallyBlock
[ self on: anErrorOrSet do: errorBlock ]
ensure: finallyBlock
that will behaves just like try:catch:finally: on java.
That's the magic of smalltalk (well, a small part of it), if there is no match for your needs, you can always extend it :)

- 4,252
- 14
- 17
I'm not sure I understood your question, but if I did and you meant "how does one handle an exception if it is triggered and continue the normal execution otherwise", this is what you can do:
[self doWhatever] on: SomeException do: [self handleSomeException].
self continueNormally.
Check out all subclasses of Exception to see what kind of exceptions you can capture.
Hope it helped!

- 1,172
- 9
- 15
-
The finally block is not only executed when execution continue normally but also when an exception unroll the stack like Smalltalk #ensure:. See other answers. – Alex Jasmin Oct 23 '11 at 08:42
This is how you can write it out of the box in almost all Smalltalk dialects.
[[ "try{}" ]
on: Error
do: [:ex | "catch{}"]]
ensure: ["finally{}"]
Or you can extend BlockClosure as @EstebanLM recommended.

- 1,208
- 1
- 12
- 22