AppleScript_ The Definitive Guide - Matt Neuburg [92]
on myHandler( )
local x
set x to 5
script myScript
on h( )
display dialog x
end h
h( )
end script
run myScript
end myHandler
myHandler( ) -- 5
I think the reason for this rule is that a handler can contain a nested scope (a script object) but has no top-level entities. A handler can't declare a property, so without this rule, it would have no encapsulated way to expose values to a nested script object. Similarly, without this rule, code in a script object in a handler would be unable to see a script object earlier in the same handler:
on h( )
script s
display dialog "howdy"
end script
script ss
run s
end script
run ss
end h
h( ) -- howdy
Scope of Globals
An explicit global is a variable whose name appears in a global declaration . A global declaration can declare several variables at once, delimited by comma:
global a
global b, c, d
Globals are rather complicated. I'll divide the discussion into two parts: the downward effect of a global declaration, and its upward effect.
Global Declarations: The Downward Effect
The downward effect of a global declaration is very much like a top-level entity declaration. A variable declared global is visible in the scope where it is defined, subsequent to the point where it is defined, and at all deeper levels within that scope, subsequent to the point where it is defined.
For example:
global x
set x to 5
on myHandler( )
display dialog x
end myHandler
myHandler( ) -- 5
The variable x is declared global; it is then visible downward into the scope of myHandler, because myHandler is defined subsequently in the same scope as x.
But the following code does not work:
set x to 5
on myHandler( )
display dialog x
end myHandler
global x
set x to 10
myHandler( ) -- error: The variable x is not defined
We keep setting x like mad, but to no avail; the global declaration doesn't come until after the handler definition, so code inside the handler can't see x.
Just as with a top-level entity, a global's downward effect is overshadowed by a local declaration of the same variable name at a deeper level, and this overshadowing affects only the scope of the local declaration—not a deeper scope.
Global Declarations: The Upward Effect
The upward effect of a global declaration of a variable is to identify that variable with a variable at the top level of the script with the same name (creating this variable if it does not already exist). This means that separate regions of scope can share a variable simply by declaring it global:
on setX( )
global x
set x to 5
end setX
on getX( )
global x
display dialog x
end getX
setX( )
getX( ) -- 5
That example demonstrates that the two handlers are sharing the same variable x. Now let's demonstrate that this x is being instantiated at the top level:
on setX( )
global x
set x to 5
end setX
setX( )
display dialog x -- 5
The fact that the last line works, rather than generating a runtime error complaining that x is not defined, shows the call to setX has defined x at the top level.
The status of a global created in this way is interesting. First, observe that it is not automatically visible downwards, as it would be if a global declaration (or a property declaration) were present at the top level. This doesn't work:
on setX( )
global x
set x to 5
end setX
on getX( )
display dialog x
end getX
setX( )
getX( ) -- error: The variable x is not defined
Even though x is a global defined at the top level, as we proved in the previous example, yet now getX can't see it. There is no global x declaration at a higher level than getX, so there is no downward effect to endow getX with the ability to see x. And getX itself now contains no global x declaration, so in effect it has failed to put in a request of its own to see x.
Global as static
A local is not persistent —it goes out of scope and is