|REBOL 3 Docs||Guide||Concepts||Functions||Datatypes||Errors|
|TOC < Back Next >||Updated: 6-Feb-2009 Edit History|
Function attributes provide control over specific function behaviors, such as the method a function uses to handle errors or to exit. The attributes are an optional block of words within the interface specifications.
Error messages typically are displayed when they occur within the function. If the catch attribute is specified, errors that are thrown within the function are caught automatically by the function. The errors are not displayed within the function but at the point where the function was used. This is useful if you are providing a function library (mezzanine functions) and don't want the error to be displayed within your function, but where it was called:
root: func [[catch] num [number!]] [ if num < 0 [ throw make error! "only positive numbers" ] square-root num ] root 4 2
root -4 **User Error: only positive numbers **Where: root -4
Notice that in this example, the error occurs where root was called even though the actual error was generated in the body of the function. This is because the catch attribute was used.
Without the catch attribute, the error would occur within the root function:
root: func [num [number!]] [ square-root num ] root -4 ** Math Error: Positive number required. ** Where: square-root num
The user may not know anything about the internals of the root function. So the error message would be confusing. The user only knows about root, but the error was in square-root.
The throw attribute allows you to write your own control functions, such as for, foreach, if, loop, and forever, by allowing your functions to pass the return and exit operations. For example, this loop function:
loop-time: func [time block] [ while [now/time < time] block ]
evaluates a block until a specific time has been reached or passed. This loop can then be used within a function:
do-job: func [job][ loop-time 10:30 [ if error? try [page: read http://www.rebol.com] [return none] ] page ]
Now, what happens when the ['return [bad-link:datatypes/none].txt] block is evaluated? Because this block is evaluated by the loop-time function, the return occurs in that function, not in do-job.
This can be prevented with the throw attribute:
loop-time: func [[throw] time block] [ while [now/time < time] block ]
|TOC < Back Next >||REBOL.com - WIP Wiki||Feedback Admin|