6

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.

milan
  • 2,355
  • 2
  • 23
  • 38

4 Answers4

7

You could wrap the #on:do block in another block that has the #ensure: attached to it.

mamboking
  • 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
5

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 :)

EstebanLM
  • 4,252
  • 14
  • 17
1

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!

Bernat Romagosa
  • 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
1

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.

Esteban A. Maringolo
  • 1,208
  • 1
  • 12
  • 22