AppleScript_ The Definitive Guide - Matt Neuburg [96]
A free variable takes its value within the handler or script object at the time the code runs, not at the time the handler or script object is defined. For example:
global x
set x to 5
on myHandler( )
display dialog x -- x is a free variable
end myHandler
set x to 10
myHandler( ) -- 10(not 5)
The dialog displays 10, not 5. It doesn't matter that x had been set to 5 when myHandler was defined; it only matters what its value is when the code inside myHandler actually runs. By that time, x has been set to 10.
Free variables' values are determined at runtime; but the identification of the fact that a variable is a free variable, and its association with some particular globally visible variable, happens during compilation. This way of resolving the meaning of free variable names is called lexical scoping .
So, in the previous example, it is important that x is declared global before myHandler is defined. If you move the global x declaration to after the myHandler definition, the script generates an error at runtime. Even if x is declared global before (temporally) myHandler runs, that's not good enough. We must declare x global before (physically) myHandler speaks of it; otherwise, myHandler's x isn't the global x, and when the code runs, myHandler's x isn't defined. This is another reason why you should declare your variables, and not only declare them but declare them early, even though AppleScript doesn't require you to do so.
Here's an example with two top-level entities as free variables. One is a property, the other is a script object:
property x : 5
script myScript
display dialog x -- x is a free variable
end script
script myOtherScript
set x to 20 -- x is a free variable
run myScript -- myScript is a free variable
end script
set x to 10
run myScript -- 10
run myOtherScript --20
Redeclaration of Variables
Redeclaration of variables is a nasty edge case, testing the limits of the language. Luckily, the compiler mostly stops you from doing it. But there is a great deal of legal nuttiness, especially among declarations at the top level of a script. Essentially AppleScript is hoist with its own petard: having ruled that variables can be declared implicitly, and that global variables exist at top level even when they are declared elsewhere, AppleScript is simply trying to cope coherently with the consequences.
Here are some examples of what happens when you redeclare a variable.
It is a compile-time error to redeclare an implicit global as local:
set x to 5
local x -- compile-time error: Can't declare x as both a local and global variable
It is a compile-time error to redeclare an implicit local as global:
on getX( )
display dialog x
global x -- compile-time error: Can't declare x as both a local and global variable
end getX
By the same token, it is a compile-time error to declare a handler parameter as global within the handler:
on myHandler(what)
global what -- compile-time error: Can't declare x as both a local and global variable
end
It is a compile-time error to redeclare as local a variable declared global in the same scope (except at the top level):
on getX( )
global x
local x -- compile-time error: Can't declare x as both a local and global variable
end getX
It is a compile-time error to redeclare as global a variable declared local in the same scope (except at the top level):
on getX( )
local x
global x -- compile-time error: Can't declare x as both a local and global variable
end getX
At the top level, it is not an error to declare a variable local and then declare it global in the same scope. But it doesn't have any effect within the top-level scope either. For example:
local x
global x
set x to 5
on setX( )
set x to 10
end setX
on getX( )
display dialog x
end getX
setX( )
getX( ) -- 10
display dialog x --5
Once x is declared global, both setX and getX have automatic access to a global variable x. But the code in the top level does not have such access. There, x has already