On 9/03/07 23:57, deivy petrescu wrote:
[...]
Ed,
First, I believe that may be semantics separates us. I mean to say the
following: setting a variable in the top level script is (almost, I'll
give you the two flavors of global) global by default. Setting a
variable in a handler is local by default.
I give you that when you declare a variable at the top level as
global, the variable is global throughout the script, including
handlers.
But with some surprises due to lexical scoping matters... (see below)
[...]
The reason is, globals are set during the script run. Since the open
does not run the script the global declaration does not take place.
Not exactly; by saving this one as an applet and dragging items on it:
-- One
on open
global G
try
set G to G + 1
on error
set G to 1
end try
displayG()
end open
on displayG()
global G
display dialog G
end displayG
it appears that G behaves as a "regular" global, even if it never
appears in the context of the (implicit or explicit) run handler.
Try property instead. It sticks because it is set at
compilation time
The above shows that globals stick too.
But in that precise example, this relies on "global" statements to be
executed (for dynamic scoping) and on the variable to be set to some
value (for coming into existence and being saved with the application).
Now, about globals, run handlers and other handlers.
I'll consider implicit run handlers.
Let's have a look at this one:
-- Two
try
set G to G + 1
on error
set G to 1
end try
displayG()
on displayG()
display dialog G
--> error: variable G is undefined
end displayG
So, having G created (because initialized) at the script's top level
isn't sufficient for the handlers to recognize it.
The most "logical" way to would be to write this:
-- Three
try
set G to G + 1
on error
set G to 1
end try
displayG()
--> 1, 2, 3...
on displayG()
global G
display dialog G
end displayG
This shows that some global entity indeed gets created in the run
handler, as an appropriately placed "global" statement allows to reach
it.
Now, let's have a look at this variant:
-- Four
global G
try
set G to G + 1
on error
set G to 1
end try
displayG()
--> 1, 2, 3...
on displayG()
display dialog G
end displayG
So, having a "global" statement at the top-level seems to be sufficient
for the handler to recognize symobol G as a global variable, not a
local one.
But this is a matter of lexical scoping too, as the position of the
"global" statement matters:
-- Five
try
set G to G + 1
on error
set G to 1
end try
displayG()
on displayG()
display dialog G
--> error: variable G is undefined
end displayG
global G
Not convinced? Let's be somewhat more perverse:
-- Six
on displayGbis()
display dialog G
end displayGbis
global G
on displayG()
display dialog G
end displayG
try
set G to G + 1
on error
set G to 1
end try
displayG()
--> 1, 2, 3...
displayGbis()
--> error: variable G is undefined
Note that one may observe similar behaviors with properties: the
locality of symbols in handlers depends on where the "property"
statement appears.
For example:
-- Seven
on displayP()
display dialog P
--> error: variable P is undefined
end displayP
property P : 0
set P to P + 1
displayP()
Of course, this is quickly repaired by using the appropriate keyword,
the same way we cured Two by Three:
-- Eight
on displayP()
display dialog my P
end displayP
property P : 0
set P to P + 1
displayP()
--> 1, 2, 3...
Now, the biggest problem with globals in AppleScript is... the
availabilty of properties (or vice-versa, depending on the point of
view).
For example, let's have a look at this variant of Eight:
-- Nine
on displayP()
global P
display dialog P
end displayP
property P : 0
set P to P + 1
displayP()
--> 1, 2, 3...
Damn! Didn't we declare P as a property?
And how about this variant of Three:
-- Ten
try
set G to G + 1
on error
set G to 1
end try
displayG()
--> 1, 2, 3...
on displayG()
display dialog my G
end displayG
Gosh! Wasn't G an implicitely declared global?
It appears that one has big scoping clashes at a script's top-level, so
that mixing globals and properties (with sometimes slightly differing
behaviors) just tends to obscure matters.
This is why I suggested to stick with properties, as they anyway have
their natural usage in AppleScript within script objects.
Axel
|