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
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.
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.
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.