• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Inheritance, Context, Scope, etc.
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Inheritance, Context, Scope, etc.


  • Subject: Re: Inheritance, Context, Scope, etc.
  • From: Axel Luttgens <email@hidden>
  • Date: Sun, 25 Jan 2004 18:03:04 +0100

Sorry, once again a bit long, so...

[ === PART I ===]

On 23/01/04 2:07, Wallace, William wrote:

[...] Emmanuel pointed out that I had the wrong definition for the error, but it didn't really help me understand what was going on there. In this case it seemed that a script object could not set the value of a global variable unless it was both declared as global AND initialized to an arbitrary value in the top level of the main script. You touch on this in your example 21, but I'd like to understand the logic behind this behavior better. [...]


On 23/01/04 19:32, Wallace, William wrote:

[...] But I still wouldn't mind hearing from Mr. Nebel (or anyone else who may know) about the underlying philosophy for this behavior. I now know how to enable child script objects to change the value of their parent's global variables, but I'm still curious as to why it is forbidden for a child script object to be able to set the initial value for a parent's global variable (I mean how could this be a bad thing?). [...]


You already got some replies to above messages, but I'm fearing you were in fact somehow confusing properties with globals, while the replies took the word "global" literally.

INHERITANCE AND SCOPE
=====================

Unless I'm wrong, the whole matter started with your message "Error Number: -10006 H-E-L-L-L-P!"; here follows a really simplified version of your original code:

-- Example 1

--main script
global w
set m to load script alias "path:to:loaded:script"
m's doIt()
display dialog w

--loaded script
to doIt()
set my parent's w to (item 1 of my parent's y)
--> error -10006: cant set w to ...
end doIt

Emmanuel provided you with the error's definition:

errOSACantAssign = -10006,
/* Signaled when an object cannot be set in a container.*/

The explanation I gave you was: "Here, nothing really usable, just a name w in the global name space. Something has thus to be created. Given the reference form "my parent's w", this should be a new property for the parent script. But script objects can't be modified; only the values of their properties may. Bang."

So, yes, you have introduced name w through the "global w" statement; but this was just a name (no value has been bound to that name).
Now, when loaded script searches for "my parent's w", it first searches for a property named w of the parent, aka the top level script (TLS).
There is none; so enters that ***very confusing behavior*** of AppleScript: loaded script then searches for a global named w.
But there is just a name, no value associated to name w.
So, a place holder has still to be created (should there have been one, it would have been used).
But the loaded script was asked to create "my parent's w" that is, a property of its parent.
Now, you can't create a new property of a script object, as that would change the object's definition.

A script object is a collection of properties, handlers and script objects intended to perform certain tasks as a kind of black box.
If needed, the behavior of that black box may be adapted by inheritance: just define a new script object as a child.
But a script object's definition can't be changed by program: you can't add (remove) components to (from) the object.
Only the values bound to existing properties may be changed.

That's a part of the philosophy.

You get exactly the same behavior with a code like this one:

-- Example 2
script S
property P : "Hey"
end script
set S's W to "Hello"
--> error -10006: Cant set W to "Hello" [1]

which clearly shows that one is attempting to add a new property to a script object, namely "script S". The same as above is happening: no property W, no global W, try to create a property (because of the "my"), error.

Or a variant:

-- Example 3
script S
on doThis()
set my W to "Hello"
--> error
end doThis
end script
S's doThis()

Anyway, the initial problem didn't go about globals at all: there was an attempt to CREATE a property.

Let's go a bit further on properties before speaking about globals.

Consider this one:

-- Example 4
property W: "Bye"
script S
on doThis()
set my W to "Hello"
end doThis
end script
S's doThis()
W --> "Hello"

So, script S finds the parent's property W and changes the value bound to it; this is really a matter of inheritance, as shown by that counter-example:

-- Example 5
property W : "Bye"
script S
property parent : application "Finder"
on doThis()
set my W to "Hello"
--> Finder error: can't set W to "Hello"
end doThis
end script
S's doThis()
W

Now, let's just remove the "my":

-- Example 6
property W: "Bye"
script S
on doThis()
set W to "Hello"
end doThis
end script
S's doThis()
W --> "Hello"

Same result as with Example 4. Hmm... must again be a matter of inheritance.
Sure? Let's see:

-- Example 7
property W : "Bye"
script S
property parent : application "Finder"
on doThis()
set W to "Hello"
end doThis
end script
S's doThis()
W --> "Hello"

We clearly couldn't have changed a Finder's property...
In fact, this has nothing to do with inheritance: it is a matter of pure syntactic scoping.
As soon as a property has been defined in the script (I really mean the text here), the name of that property may be used "as is" past that point, where it makes sense and unless overridden by an other statement.

Where it makes sense:

-- Example 8
script S
property W : "Bye"
on doThis()
set W to "Hello" -- Use W as is
end doThis
end script
S's doThis()
S's W -- Right: W belongs to S
--> "Hello"
W -- No such top-level data
--> W is undefined

Unless overridden - one way to do it:

-- Example 9
property W : "Bye"
script S
property W : "Hoyado" -- This hides above W
on doThis()
set W to "Hello" -- So we use the latter
end doThis
end script
S's doThis()
S's W --> "Hello"
W --> "Bye"

Unless overridden - another way to do it:

-- Example 10
property W : "Bye"
script S
on doThis()
local W -- Confine W to the handler
set W to "Hello" -- So this will be lost
end doThis
end script
S's doThis()
W --> "Bye"

But again, this is purely a syntactic scoping matter, occurring within a same script text: nothing to do with inheritance, nor even with objects...

That syntactic aspect is even clearer through following example:

-- Example 11
script S
on doThis() -- I haven's seen W yet
set W to "Hello" -- So I'll take it as local
end doThis
end script
property W : "Bye"
S's doThis()
W --> "Bye"

But, as soon as the "my" keyword is used, this indicates one's intent to reach a property [2]:

-- Example 11
script S
on doThis()
set my W to "Hello" -- Oh, my parent has one
end doThis
end script
property W : "Bye"
S's doThis()
W --> "Hello"


------------
[1] This is the error when run as an application. In SE, the error is: "error 10: NSCannotCreateScriptCommandError".
Which one do you prefer? ;-)
[2] With the usual caveat: if I inherit from the TLS, if there is no such property, but there is a global, well take that one...

[ === GO TO PART II === ]
_______________________________________________
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.

References: 
 >RE: Inheritance, Context, Scope, etc. (From: "Wallace, William" <email@hidden>)

  • Prev by Date: Re: Folder action question
  • Next by Date: Re: Inheritance, Context, Scope, etc.
  • Previous by thread: Re: Inheritance, Context, Scope, etc.
  • Next by thread: Re: Inheritance, Context, Scope, etc.
  • Index(es):
    • Date
    • Thread