AppleScript_ The Definitive Guide - Matt Neuburg [81]
The names of the parameters within the handler, such as x and y in this example, designate variables local to the handler. The meaning and significance of this is explained in Chapter 10, but the key fact is that the names of the parameters in the handler definition have nothing to do with the names of the values passed as parameters. Consider this example:
on subtract(x, y)
return x - y
end subtract
set x to 2
set y to 3
subtract(y, x) -- 1
The handler subtracts y from x. If these were the same as the y and x at the top level of the script, you'd expect the result to be negative (we'd be subtracting 3 from 2). But in the handler call, the names are not what matters—the values are. The value 3 is passed as the first parameter and becomes x within the handler. The value 2 is passed as the second parameter and becomes y within the handler.
Pass by Reference
Parameters passed to a handler, and the value returned from a handler, are normally passed by value in AppleScript. This means that a copy of the value is passed to, and used by, the handler code.
But four datatypes—lists, records, dates, and script objects—when they are passed as parameters to a handler, are passed by reference , meaning that no copy is made; the handler and the caller both end up with access to the very same value. These are the only mutable datatypes—the only datatypes whose values can be modified in place. Whatever mutation is made to the parameter by the handler applies to it in the context of the caller as well. (Compare "Set by Reference" in Chapter 7.)
Here's an example showing that a list is passed by reference:
on extend(LL)
set end of LL to "Jack"
end extend
set L to {"Mannie", "Moe"}
extend(L)
L -- {"Mannie", "Moe", "Jack"}
Even though the caller didn't capture the value of the handler call extend( ), and even though the caller didn't change L, and even though the handler extend never speaks explicitly of L, yet after the call, L has changed in the caller's context. The handler extend was able to modify L.
Here's an example showing that a script object is passed by reference:
script myScript
property x : 10
end script
on myHandler(s)
set s's x to 20
end myHandler
myHandler(myScript)
display dialog myScript's x -- 20
It makes sense that these datatypes can be passed by reference, but it is a little disturbing that they are passed by reference automatically, without giving you any choice in the matter. Passing by reference gives the handler great power over the parameter, which the handler can misuse. So, to prevent accidents, it is up to you to remember that list, record, date, and script object parameters are passed by reference, and that things you do in a handler to such parameters have an effect outside the handler. If you wish to avoid this, then if you like you can pass them by value, by making a copy and passing the copy:
on byValue(x)
copy x to y
return y
end byValue
on extend(LL)
set end of LL to "Jack"
end extend
set L to {"Mannie", "Moe"}
extend(byValue(L))
L -- {"Mannie", "Moe"}
What about values that are not lists, records, dates, or script objects? How can they be passed by reference? They can't. Well, sometimes they can, but only in situations where it is pointless to do so. See "Reference as Parameter" in Chapter 12.
Syntax of Defining and Calling a Handler
The way a handler is defined (in the on line) states how many parameters the handler takes (and also supplies names for variables in the handler to which the parameter values will be assigned during a call). A call to the handler must correspond, supplying parameters correctly. It is a runtime error to call a handler with fewer parameters than the definition of the handler requires:
on greet(what)
display dialog what
end greet
greet( ) -- error: {} doesn't match the