control structure



You can use always to identify code that will run regardless of whether a throw occurs.

The always keyword begins a block of code—known as a clause—that will be executed at the end of a lexical scope. Only a halt-everything will cause the always clause not to be executed. The code in the always clause is executed at the end of the scope, even if a something occurs which would otherwise cause the scope to terminate. The always clause will be executed even if you exit the scope with a throw, return, exit, or halt.

The always clause must be the last clause in a lexical scope, occurring after any catch clauses in the scope. In this example, the reopen action will throw to #external-exception if main-log is not initialized.

  include ""
  global stream main-log ; This should be set from command-line.
     local stream log-stream 
     reopen log-stream as file main-log
     put log-stream "The program ran at: " || date "=xY-=M-=D =h:=m:=s" || "%n"
   catch #program-error 
     output "Something went wrong. Don't know what it was.%n"
     put #error "The program terminated at: " || date "=xY-=M-=D =h:=m:=s" || "%n"

You may want to include more than one always clause in a scope. If an error or throw occurs in an always clause, the rest of that block will not be executed, but a subsequent always clause in the same scope will be executed. This allows you to make sure that each always operation is executed, even if there is an error in executing a previous one.

When a throw to catch-name is initiated in a nested scope and caught at an outer level of nesting, code is executed in the following sequence:

  1. any always clauses in the scope of the throw, in the order they appear,
  2. any always clauses in intermediate scopes between the throw and the catch catch-name, in the order they appear,
  3. the catch clause of catch-name, and finally
  4. any always clauses in the scope of the catch catch-name, in the order in which they appear.