Creating Script Objects dynamically

howdy–

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?

Thanks

Use a constructor function. e.g.


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

You usually store the scripts in lists.

gl,

Thanks!

I also just figured out changing

set thisObject to ScriptObj

to

copy ScriptObj to thisObject

worked as well.

Hi,

the problem is the line

set thisObject to ScriptObj

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.

Thanks, everyone!

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.

HTH

Duly noted. This is awesome stuff. Thanks for all the help!