always

control structure

Syntax
always


Purpose

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

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

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

  include "omdate.xin"
  global stream main-log ;set from command line
  
  process
    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"
    always 
      put #error "The program terminated at: " 
        || date "=xY-=M-=D =h:=m:=s" 
        || "%n" 

You may want to include more than one always block in a scope. If an error or throw occurs in an always block, the rest of that block will not be executed, but a subsequent always block 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 is initiated in a nested scope and caught at an outer level of nesting, code is executed in the following sequence:

  1. any always blocks in the scope of the throw, in the order they appear
  2. any always blocks in intermediate scopes between the throw and the catch, in the order they appear
  3. the catch block of the catch
  4. any always blocks in the scope of the catch, in the order in which they appear