von dp am 22.Dezember 96 um 19:10:24:
zu: Perlen aus dem Strom der Nachrichten im direct_L von Daniel am 22.Dezember 96 um 02:00:59:
A better method for storing and retrieving lists in cast members
von Gretchen McDowall (updateStage)
Jan Stout writes in with another method for storing lists which is quite a bit faster both in the
storing and in the retrieval. Jan suggests storing your list hardcoded into a script (it doesn't
matter what type of script - cast, movie, frame) in a format similar to the following:
on returnList me
return [ #item1, #item2, #item3 ]
end
To retrieve the list from the script you do this:
set theList = returnList( script "ListStorage" )
This would not be very useful if you had to type the whole list into the script by hand, but you
don't. Instead you use the scriptText property to put the list and the code for returning it, into
the script like this:
on storeList aList
set the scriptText of script "ListStorage" to "on returnList me" & RETURN &
"return" & string(aList) & RETURN & "end" & RETURN
end
This doesn't solve the big list problem, since scripts are limited to 32K just like fields, but it
really is much peppier. In a test I did storing the identical 2500 item list into a script and into a
field, storage into the script was 26 times faster than into the field and retrieval from the script
was 11 times faster than retrieval from the field. Zowee!
Jan also sent the code he uses to convert a list into a string before storing it. His code intercepts
void values that will prevent the list from reconstituting. It also does not put in extra spaces,
which saves on storage.
Here is a list converted using Lingo's string function:
put string([2,"cat",#prop,undefinedVariable])
-- "[2, "cat", #prop, Void]"
Here is the same list converted using Jan's code:
put listToString([2,"cat",#prop,undefinedVariable])
-- "[2,"cat",#prop,integer(#void)]"
The listToString code is a little tricky to understand at first, because it is recursive - it calls itself.
It could have been written as two separate handlers. The top part (above "separator") accepts
one list item and returns a storage-ready version of it. The bottom part iterates through a list
and passes itself each list item to convert. If the code is called with a list item, the code doesn't
execute beyond the separator line because the list item will meet one of the conditions in the
top part and be returned.
on listToString l
-- similar to string(), but
--
-- - without unnecessary spaces
-- - with a parseable void value
if floatP(l) then return l
if integerP(l) then return l
if stringP(l) then return QUOTE & l & QUOTE
if symbolP(l) then return "#" & l
if voidP(l) then return "integer(#void)"
if not(listP(l)) then return string(l)
set n = count(l)
if n = 0 then return "[]"
--
------ separator ---------------
--
if ilk(l, #linearList) then
set r = "[" & listToString(getAt(l, 1))
repeat with i = 2 to n
put "," & listToString(getAt(l, i)) after r
end repeat
else
set r = "[" & listToString(getPropAt(l, 1)) & ":" &¬
listToString(getAt(l, 1))
repeat with i = 2 to n
put "," & listToString(getPropAt(l, i)) & ":" &¬
listToString(getAt(l, i)) after r
end repeat
end if
put "]" after r
return r
end
D. Plänitz