advice for optimizing iteration of objects list

Hi all,

Context:
The purpose of this script is to take à list of files/folder as input and construct an object for each file/folder.
The object is a suit of properties set after running a serie of test: so far so good.

I need then to gather those objects into a list and run tests on their properties to classify them (moving the object or copying properties to a different list).
The script below is a simpler representation of the “real life” version:


script test
	property stuff : ""
	to dosome(val)
		set stuff to "val_" & val
	end dosome
end script

set a to {}
repeat with i from 1 to 10 -- <= change value here
	tell test to dosome(i)
	copy test to tmp
	set a to a & tmp
end repeat

set b to {}
repeat with i from 1 to (count of a)
	set b to b & stuff of (item i of a)
end repeat

return b

Prob: It seem to crash after creating 15 to 20 objects (script editor not responding), whereas looping up to 10 times works fine.
Quest 1: is there a better way to list objects and be able to retreive them using the “item” reference (wich a “record” wouldn’t let me do)
Quest 2: is there some form of declaration that creates an new object much like in php using the “new object_class()” syntaxe in applescript

cheers - nico

Quick comments: When appending to a list, it is more efficient to use “end of” or “beginning of” than to concatinate:

set a to a & tmp
-- is better as:
set end of a to tmp

Why are you copying all of test to tmp and then appending that to a? Remember that you’re creating a rapid expansion of the memory used here.

thanks adam.
the copy to “tmp” was a workaround to my lack of knowledge.
I now use the

copy test to (end of a)

which gives me a nice list of objects, though it still incredibly fills up the memory.

is there some sort of multi dimensional array in applescript that we can access by numerical index as well as by text reference?

Model: G5 dual core / 2gigs ram
AppleScript: 1.9.2
Browser: Safari 417.8
Operating System: Mac OS X (10.4)

Hi, Boudros.

I too am puzzled about why you want to use script objects here. If you just need collections of named properties then records would be much better:

to dosome(val)
	return "val_" & val
end dosome

set a to {}
repeat with i from 1 to 200 -- <= change value here
	set test to {stuff:""} -- Presumably more properties in the real situation.
	set test's stuff to dosome(i)
	set end of a to test
end repeat

set b to {}
repeat with i from 1 to (count of a)
	set end of b to stuff of (item i of a)
end repeat

return b

If it’s really necessary to use script objects, you can more economically use “children” of the original rather than duplicates. These would “inherit” the handler from the original instead of containing their own copies. But they could have their own copies of ‘stuff’. (Note that you have to tell each “child” to set its own property to the handler result. Having the handler set the property will cause confusion in the inheritance system.):

script test
	property stuff : ""

	to dosome(val)
		return "val_" & val
	end dosome
end script

set a to {}
repeat with i from 1 to 200 -- <= change value here
	-- Initiate a "child" of the script object 'test', with its own 'stuff' property.
	script t
		property parent : test
		property stuff : ""
	end script
	
	tell t to set its stuff to dosome(i)
	set end of a to t
end repeat

set b to {}
repeat with i from 1 to (count of a)
	set end of b to stuff of (item i of a)
end repeat

return b

Don’t use ‘copy’ on script objects; it not only duplicates the script object in question but all of its parent objects as well, which generally ends up meaning your entire script and everything in it. (The default parent for a script object is the top-level script.) This causes all kinds of unhealthy.

AppleScript uses a kind of prototype-based OOP, though using ‘copy’ to clone objects is a bad idea as I say. Recommended approach is to define a constructor function that creates new script objects on demand, e.g:

on makeFoo(param)
    script Foo
        property _val : param

        on doSomething()
            return _val
        end doSomething
    end script
    return Foo
end makeFoo

If you want to see some real-world examples of AppleScript OOP, I’ve done quite a bit in some of the libraries on AppleMods, e.g. the Types library is a good one to start on.

HTH

Many thanks again, I wasn’t expecting so much interest and advice.

Nigel: I went for the the record suggestion you made. Indeed faster than objects / cheers.
hhas: I now understand why the memory usage increased so much, indeed the real life script is much heavier wich explains my problem if it was beeing duplicated every time.
Also, about the OOP thing, I droped the script object idea for now, but I just discovered through your example that methods declared with “on”, in script objects, are executed at on run!
I’ll sure give a thorough look at your web site.

good day to yous.
boudros

The poor speed, like the high memory consumption, is due to the massive amount of copying going on. As long as you use constructor functions it’ll be plenty fast enough. Go with whichever approach works best architecturally.

Nope; handlers only execute when you call them.