Getting Started Documentation Glish Learn More Programming Contact Us
Version 1.9 Build 1556
News FAQ
Search Home


next up previous contents index
Next: Input/Output Logging Up: Debugging, Logging, and Error Handling Previous: Debugging, Logging, and Error Handling


fail Statement

The fail statement is used for explicitly handling errors. In Glish, fail refers to both a value and a statement. As a statement, fail is an alternate return statement and the only way to generate values of type fail. As a value type, fail is unique because if a value of type fail is passed as a parameter to a function, the function is not invoked, but rather the result of the function is the fail value which was passed as a parameter. The same is true for the evaluation of expressions containing fail values. This property allows fail values, once generated, to be propagated.

Here is a simple example of how fail values are used:

    func divide( dividend, divisor )
        {
        if ( divisor == 0 ) fail "division by zero"
        return dividend / divisor
        }
Here the function simply checks for division by zero. So now if this function is called with a divisor of 0:
    func try1(x,y) divide(x,y)
    func try2(x,y) try1(x,y)
    func output(x) { print x }
    output(try2(34,0))
the output looks something like:
    <fail>: division by zero
            Stack:  divide()
                    try1()
                    try2()
                    output()
The result contains the message with which fail was called, and the call stack to where the error occurred. Notice that output() does not have to check to verify that it has not been passed a fail value. When a fail value is passed to a function, the function is not invoked, but the return value of the function is the fail value it was passed, and the print out of this value is the output shown.

Additionally, fail values which are not handled are automatically propagated. Handling a fail value is defined to be checking it's type with one of the type identification functions (see § 10.1, page [*]). With automatic propagation, if the generated fail value is not handled before the current function returns then the result of the current function is also a fail value. This is true even though the fail value was generated earlier in the function execution, perhaps much earlier. Because Glish does not do control flow analysis of functions prior to execution, it has no way of determining if a fail value will be handled at the time it is generated.

It is possible to suppress this automatic propagation of non-handled fail values when Glish is started with the -noaf command line flag. This flag may be removed in the future.

The function is_fail() is available to check to see if a value has type fail. If so, this function returns T, otherwise it returns F. This function can be used to immediately propagate fail values; for example (continuing the above example):

    func try3(a,b)
        {
        x := try2(a,b)
        if ( is_fail(x) ) {
            print "problem!"
            fail
            }
        return a + b * 2
        }
    print try3(8,2)
    print try3(8,0)
The output produced by this code segment looks like:
    12
    problem!
    <fail>: division by zero
        Stack:  divide()
                try1()
                try2()
                try3()
In theory, this use of is_fail() should only be necessary when there are intermediate values produced, here x, on which the return value does not depend. In practice, this may not be the case.


next up previous contents index
Next: Input/Output Logging Up: Debugging, Logging, and Error Handling Previous: Debugging, Logging, and Error Handling   Contents   Index
Please send questions or comments about AIPS++ to aips2-request@nrao.edu.
Copyright © 1995-2000 Associated Universities Inc., Washington, D.C.

Return to AIPS++ Home Page
2006-10-15