I’m just starting out with Script Objects and I have question that’s crucial to what I’m trying to accomplish. Here’s the code I’m plaing around with right now just to see if this works…
property ObjList : {}
script ScriptObj
property mOffset : ""
end script
repeat with n from 1 to 10
set thisObject to ScriptObj
set mOffset of thisObject to n
set end of ObjList to thisObject
end repeat
return ObjList --all objects show "10" for the mOffset
I’ll be looking for various pieces of text in a page layout application based on specific parameters and converting them to outline form elsewhere. It would make the coding of this way easier if I could use objects rather than my crazy idea of a series of lists, because I won’t know how many objects I’m going to find (if any) or in what order I’ll be listing them until I have all of them.
My problem is that it looks as though I can’t dynamically create a script object and have it be a new unique object each time, because I get returned what is essentially the same object every time. is there a way to do dynamically create script objects and work with them as proper OOP objects?
repeat with p from 1 to 5
set this_script to MakeScript(p)
display dialog (some_prop of this_script)
end repeat
--
on MakeScript(p)
script
property some_prop : p
end script
end MakeScript
with set you copy the reference of the object,
so both variables point to the same object.
If the value of the object changes, both variables change, too
Copy copies only the value, not the reference
property ObjList : {}
script ScriptObj
property mOffset : ""
end script
repeat with n from 1 to 10
copy ScriptObj to thisObject
set mOffset of thisObject to n
set end of ObjList to thisObject
end repeat
return ObjList
Don’t use ‘copy’ to duplicate script objects within a script unless you really know what you are doing and are certain it’s what you actually need. AppleScript’s ‘copy’ command does a deep copy, which means it doesn’t duplicate that object, but also every object it contains [1] and, more importantly, its parent object and all of its contents and parent, and so on. Since the topmost parent is normally your top-level script, that means your entire script(!) is getting duplicated each time you call ‘copy’, so in addition to messing up any (intentionally) shared state in your program, you can easily end up reducing AppleScript to a crawl or crashing it completely due to sheer object overload if you’re not extremely careful.
Assuming you need to use script objects at all (and unless you’re producing module-based or object-oriented code they’re pretty much overkill compared to using simple records), 99.999% of the time, a constructor function like Kel’s is what you should use and will work without any problems.
HTH
[1] Except objects identified by reference, in which case it only copies the reference object and not the object it points to.
While playing around with this a bit more, I cooked up this as well, thogh it’s sounding like overkill/duplication of efforts…
property ScriptObjectList : {}
--the object
script ScriptObject
property mIndex : ""
end script
--create an initial "blank" object
copy ScriptObject to ScriptObjectINIT
set mIndex of ScriptObjectINIT to "-1"
repeat with n from 1 to 5
copy ScriptObjectINIT to mScriptObject --copy to a new object from the INIT object and not the original declared object.
set mIndex of mScriptObject to n
set end of ScriptObjectList to mScriptObject
end repeat
return ScriptObjectList
I’ll explore the constructor method some more.
I work with college textbooks a lot (pulling content out, transforming content, and scripting the creation of various ancillaries), and objects for some of the work is something I’ve been working towards for quite some time. I also work in another OOP language so I (vaguely) aware of the dangers here. I should also note that the use of objects in this instance will be that they get used for some simple storage and sorting, and then ignored; so no parent/child relationships here.
All script objects have a parent; by default, this is the script object that it’s declared in. So it’s always an issue when using ‘copy’ to clone existing script objects due to 'copy’s overzealous behaviour. Example:
script ScriptObject
end script
property ScriptObjectList : {}
set n to 50
repeat n times
copy ScriptObject to end of ScriptObjectList
end repeat
Note: be prepared to force-quit Script Editor when you run this if n is much above 5. And if you’re not sure why it’s grinding so bad, think about what’s happening with ScriptObjectList: the entire script, including ScriptObjectList itself and everything in it, is being deep-copied and appended to ScriptObjectList each time the loop executes. In other words, the number of objects being copied increases exponentially over time.
Your last script avoids the cumulative copying effects of demonstrated here since you’re copying a copy of your entire script each time, and it’s only in the original script that ScriptObjectList is being added to. You’re still copying a lot of excess objects though, and in a larger, more complex program that’s unlikely to be healthy, so the best thing is just to stick to using constructor functions, which avoids the whole mess entirely.