9.2. Returned ValueWhen a handler is executed, it may return a value. This value is the handler's result . When a handler is called, the result of executing the handler is essentially substituted as the value of the call that executed the handler. For example: on getRam( ) set bytes to system attribute "ram " return bytes div (2 ^ 20) end getRam The handler getram returns the amount of RAM installed on the user's machine, in megabytes. On my machine, it returns the number 1024. This means that a call to getram( ) can presently be used wherever I would use the number 1024; in effect, it is the number 1024. For example: on getRam( ) set bytes to system attribute "ram " return bytes div (2 ^ 20) end getRam display dialog "You have " & getRam( ) & "MB of RAM. Wow!" The call to getram( ) in the last line behaves exactly as the number 1024 would behave in this context: it is a number, it is implicitly coerced to a string and concatenated with the other two strings (as explained under "Concatenation Operator" in Chapter 15), and the full resulting string is displayed to the user. The value returned by a handler is determined in one of two ways:
If a handler returns no value, there is no error; but in that case it is a runtime error to attempt to use the call as if it had a value. The status of such a call is similar to that of a variable that has never been assigned a value (see "Declaration and Definition of Variables" in Chapter 7). So, for example, there's nothing wrong with this: on noValue( ) return end noValue set x to noValue( ) After that, even if x was previously defined, it is now undefined. That outcome is actually useful if you wanted to undefine x; there's no other way to do it. But remember, a subsequent attempt to fetch x's value will generate a runtime error: on noValue( ) return end noValue set x to 1 set x to noValue( ) set x to x + 1 -- error: The variable x is not defined The result of a handler is volatile. It is substituted for the call, but the call itself is not storage (it isn't a variable), so the result is then lost. If you wish to use the result of a handler again later, it is up to you to capture it at the time you make the callfor example, by setting a variable to it. Of course, you could just call the handler again; but there are good reasons why this strategy might not be right:
So, for example, this code works, but it is very poor code: on getRam( ) set bytes to system attribute "ram " return bytes div (2 ^ 20) end getRam set s to "You have " & getRam( ) & "MB of RAM. Wow! " set s to s & getRam( ) & "MB is a lot!" display dialog s The handler is called twice to get the same unchanging result, which is very inefficient. The right way would be more like this: on getRam( ) set bytes to system attribute "ram " return bytes div (2 ^ 20) end getRam set myRam to getRam( ) set s to "You have " & myRam & "MB of RAM. Wow! " set s to s & myRam & "MB is a lot!" display dialog s The second version calls the handler and immediately stores the result in a variable. Now it suffices to fetch the value from the variable each time it is needed. The result of a handler may be ignored, though, if the caller doesn't care about it (or knows that no value will be returned). In this case the handler is called entirely for its side effects. Generally the call will appear as the only thing in the line: eraseMyHardDisk( ) The same is equally true for the run handler of a script object (or a script as a whole), whether implicit or explicit. A run handler is a handler, and can have a result (possibly a useful result). After you run a script in a script editor application, the result is displayed; if no return statement was encountered, the result displayed is the implicit result of the run handler of the script as a whole. (This fact can be useful in developing and testing a script; see "Implicit Result" in Chapter 5.) A script runner, on the other hand, will usually ignore a script's result, neither capturing it nor displaying it; the script is executed entirely for its side effects. |