Re: Inheritance, Context, Scope, etc.
Re: Inheritance, Context, Scope, etc.
- Subject: Re: Inheritance, Context, Scope, etc.
- From: Axel Luttgens <email@hidden>
- Date: Sun, 25 Jan 2004 18:03:41 +0100
[ === PART II === ]
As a side note: one could be tempted to believe that:
-- Example 12
-- main script
property W: "Bye"
set S to load script alias "path:to:loaded:script"
S's doThis()
-- loaded script
on doThis()
set W to "Hello"
end doThis
and:
-- Example 13
property W: "Bye"
script S
on doThis()
set W to "Hello"
end doThis
end script
S's doThis()
are two equivalent things.
Well, not at all. [3][4]
In Example 12, identifier W is the name of a variable local to handler
doThis(), since that identifier doesn't appear before in the loaded
script's text.
In Example 13, because identifier W appears before the doThis()
handler's definition, doThis() will act upon the TLS property.
As a brief summary:
The original problem arose because of the attempt to create a property,
not because of some obscure impossibility for a script object to
initialize global variables.
Creating a property would modify the structure of some script object,
and this is the reason for not being able to do such a thing.
Finally, some syntactic scoping rules may extend the visibility of a
property's identifier in such a way that the "my" keyword is not allways
needed to refer to that property.
GLOBALS ARE NOT INHERITED
=========================
This section is motivated by the locution "parent's global variables"
you used twice in the introductive excerpts.
I don't know if it went just on typos, or if there really was some
confusion.
So, just to be sure... (and my apologies if there was no confusion).
Let's take an example of inheritance:
-- Example 14
script Pa
property parent : application "Finder"
property W : "Bye"
on doThis() -- Due to syntactic rules,
set W to "Hey" -- my is not required here
end doThis
end script
script Son
property parent : Pa
on doThat() -- But my is required here
my W -- if I want to refer my
end doThat -- parent's property
end script
Pa's doThis()
Son's doThat() --> "Hey"
and slightly adapt it that way:
-- Example 15
script Pa
property parent : application "Finder"
on doThis()
global W
set W to "Hey"
end doThis
end script
script Son
property parent : Pa
on doThat()
my W --> Finder error: can't get W
end doThat
end script
Pa's doThis()
Son's doThat()
So, even if W has been defined from within Pa, Son doesn't seem to have
heard about it.
One could say: hey, that's cheating, as the message told about a Finder
error!
True, but the Finder complained because of an unsuccessful search for
something named "W" in script Pa, which then asked the Finder to find
such a thing.
Reply: yeah, that's because of the "my" keyword; I've asked Pa to create
a global, not a property!
Well, it is clear that removing "my" from the definition of doThat()
can't be the solution, as W would just be taken as a variable local to
the handler (resulting in a undefined variable error).
So, here is the way:
-- Example 16
script Pa
property parent : application "Finder"
on doThis()
global W
set W to "Hey"
end doThis
end script
script Son
property parent : Pa
on doThat()
global W
my W
end doThat
end script
Pa's doThis()
Son's doThat() --> "Hey"
W --> "Hey"
Script Pa initialized variable W, and moreover indicated that the
identifier belongs to the global name space.
That way, script Son may get the value of that variable, just by
indicating that identifier W has to be taken from the global name space too.
Moreover, the last statement of Example 16, the one taking the value of
W, returns "Hey" too.
This CAN'T BE INHERITANCE, as how could the TLS have inherited from Pa
or from Son?
Before going further with that point, here's an example involving two
unrrelated scripts and nevertheless able to share data through globals:
-- Example 17
script S1
property parent : application "Finder"
global W
set W to "Hey"
end script
script S2
property parent : application "Preview"
global W
W
end script
tell S1 to run
tell S2 to run --> "Hey"
And this even works without any script objects at all: [5]
-- Example 18
on setW()
global W
set W to "Hey"
end
on getW()
global W
W
end
setW()
getW() --> "Hey"
Add to the preceding facts the definition of script objects: a
collection of properties, handlers and script objects.
The conclusion is that global variables must be distinguished from
properties, as they are very different beasts. [6]
In fact, you can think about the internal handling of globals and
properties as the construction and maintenance of two different tables.
Conceptually, at the end of Example 16's execution, one would have
something like this:
Table of globals Table of properties
identifier bound to identifier belongs to bound to
W "Hey" parent Pa app "Finder"
parent Son script Pa
This explains why such things are possible: [7]
-- Example 19
script S
property P : "Prop P"
on doThis()
global P
set P to "global P"
end doThis
on doThat()
my P
end doThat
on andThat()
global P
P
end andThat
end script
S's doThis()
S's doThat() --> "Prop P"
S's andThat() --> "Global P"
---------
[3] Oh gosh, that guy and his perpetual dei ex machina...
[4] Of course, there is also the potentially different behaviors when
run as an application or within SE; for example, just add the "my" keyword.
[5] Beside, of course, the TLS we can't avoid...
[6] Even if you sometimes have clashes due to that search for globals
when a TLS's child (or grand-child, or ...) can't find a property.
[7] If you try such things (to have properties and globals bearing
identical names) at the top level of your script, the clash is even
bigger: the global allways hides the property.
[ === GO TO PART III === ]
_______________________________________________
applescript-users mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/applescript-users
Do not post admin requests to the list. They will be ignored.