AppleScript_ The Definitive Guide - Matt Neuburg [93]
on incrementOrReport(report)
global ct
if report then return ct
try
set ct to ct + 1
on error
set ct to 1
end try
end incrementOrReport
incrementOrReport(false)
incrementOrReport(false)
incrementOrReport(false)
incrementOrReport(true) -- 3
However, that is really poor programming style; a script object and a property would let you do this in a far more encapsulated way.
Global as script property
A global is, in fact, persistent between script executions, just like a script property. This is a little tricky to prove, because we need a way to initialize the global only just in case it isn't already defined; to do this, I'll have to use some syntax we haven't discussed yet (see "Errors" in Chapter 19):
on setX( )
global x
try
set x to x + 1
on error
set x to 5
end try
end setX
on getX( )
global x
display dialog x
end getX
setX( )
getX( ) -- 5, then6, and so on
Indeed, a global isn't merely like a script property; it is a script property. Again, I have to be a little tricky to prove it to you:
on setX( )
global x
set x to x + 1
end setX
on getX( )
global x
display dialog x
end getX
setX( )
getX( ) -- 6, then 7, and so on
property x : 5
In that example, I deliberately postponed the property declaration until after all the other code, to show that it isn't the property declaration itself that is making x visible in lower scopes (remember, a top-level entity is visible to nested scopes only after its declaration). Thus it must be the global declarations within setX and getX that are identifying x with the script property x at the top level.
Here's another way to show that a global is a script property: I'll use a global to give the anonymous top-level script a name , and then I'll speak of another global as a property of the top-level script. This is a rewrite of a device from "The Implicit Parent Chain" in Chapter 8, using globals instead of properties at the top level:
global topLevel, x
set topLevel to me
set x to 5
script s
property x : 10
display dialog topLevel's x
end script
run s -- 5
Observe that a global declaration lets a scope region refer to an entity defined at the top level of the script, even when its name is overshadowed by a top-level entity at a deeper level:
global x
set x to 10
script outer
property x : 20
script inner
global x
display dialog x
end script
end script
run outer's inner -- 10
Without the global x declaration in inner, inner's x would be outer's property x, and the script would display 20. This script works the same way if the top-level x is declared as a property, not a global; they are the same thing. Thus we have another solution to the problem of how to speak of the top-level entities of a script as a whole even though it is anonymous (see "The Implicit Parent Chain" in Chapter 8).
The double effect of global declarations
In working with explicit globals, remember that every global declaration has both the downward and upward effect at the same time:
script myScript
global x
on myHandler( )
set x to 5
end myHandler
myHandler( )
end script
on getX( )
global x
display dialog x
end
run myScript
getX( ) -- 5
In myScript, the global x declaration does two things: it creates the top-level global x (upward effect), and it gives myHandler access to it (downward effect). Thus myHandler is able to set the value of the top-level global that will later be seen and displayed by getX.
Scope of Undeclared Variables
In AppleScript, you do not have to declare variables. When you use a name that, by the preceding rules of scope, is not an existing variable, AppleScript does not complain; rather, it creates the variable for you. How it does this depends upon the location of the code that uses the nonexistent variable name:
Code at the top level
The variable is created as a global. There is no explicit