The script in question is below. It concatenates sublists to leave only the parent list so that items of the previous sublists would populate the parent list only.
I need to see the result upon completion of each loop and the result is of the class “list” stored in the varible [format]items_to_process[/format] The script successfully writes the contents of the variable as list but fails to read it back similarly as list. Instead, the OS returns a very strange “error of type -116”. I already learned that this error means memory depletion (as per this description at http://www.cs.cmu.edu/afs/cs/user/lenzo/html/mac_errors.html) however that doesn’t solve the reason for this error to occur, in the first place. Would you point me to a mistake I made?
set items_to_process to {{}, {"Affinity Designer", "Affinity Photo", {}, {}, {}}, {}, {}, {}}
JoinListItems(items_to_process)
set theFile to (((path to desktop) as text) & "Concatenated-log") as alias
read theFile as list
on JoinListItems(items_to_process)
set Concatenated to {}
set IsJoined to false
repeat until IsJoined
set IsJoined to true
repeat ((count items_to_process) - 1) times
set Concatenated to (item 1 of items_to_process & item 2 of items_to_process)
if (count items_to_process) = 2 then
set items_to_process to Concatenated
exit repeat
end if
set items_to_process to {Concatenated} & ((items 2 thru -1) of (rest of items_to_process))
set theFilePath to (((path to desktop) as text) & "Concatenated-log")
set LogFile to open for access file theFilePath with write permission
set ThePosition to get eof file theFilePath
write items_to_process to LogFile as list starting at ThePosition
close access LogFile
end repeat
repeat with anItem in items_to_process
if class of contents of anItem is list then
set IsJoined to false
my JoinListItems(items_to_process)
end if
end repeat
end repeat
return items_to_process
end JoinListItems
What result are you trying to achieve? You’re repeatedly and recursively writing lists to the end of the file, overwriting the last byte in the file each time. That seems to be what’s causing the ‘read’ failure. The ‘write’ line should be:
write items_to_process to LogFile as list starting at eof
‘eof’ is the insertion point at the end of the file. When you use ‘get eof’, you effectively get the index of the last byte in the file, so writing from there overwrites that byte. ‘starting at eof’ ensures that writing begins after the last byte.
That said, the ‘read’ command only seems to read to the end of the first list it encounters, so even when the ‘write’ command’s corrected, only the first list written is read back — unless (presumably) you know at which byte each subsequent list begins and can specify the read to start from there.
You don’t have any error trapping to close the file in the event of the script crashing while it’s open!
That’s because I’m dealing with at least a known error and know how to trap it so I made this sacrifice intentionally.
That was quite a revelation and I never read about these nuances. I presumed that get eof implies the end position as well and nowhere did I come across the notion of (get eof) meaning something other than the end of a file. In fact, I can hardly grasp the difference between the end of a file and the index of the last byte of the file: don’t they pertain to the same thing?
which is unexpected because what I wanted was to append the list variable containing the value as it appears at the end of each loop cycle to the same file (Concotenated-log). I want to get the following:
[format]{items after the 1st cycle}
{items after the 2nd cycle}
…
{items after the last cycle}.[/format]
No. Sorry. I didn’t explain it very clearly. The eof — the end of the file — is the insertion point immediately after the last byte in the file. Any data appended to the file have to be written from there, so we write ‘starting at eof’.
The ‘get eof’ command returns “the length, in bytes, of a file”. The person who thought up the name for the command was probably thinking of the “length” as the distance between the insertion point at the beginning of the file and the eof at end. When thought of as a count, this is the number of bytes in the file, which number is also the index of the last byte. If a write begins there, the last byte gets overwritten.
In my tests, the ‘read’ command will only read one list from the file at a time. You can either store all your list results in a containing list and just write that to the file when you’ve finished, or stick to your original idea and use a repeat to read and log lists from the file like this:
set fref to (open for access theFile)
-- The file is now open for access with the file pointer at the beginning.
try
-- Keep reading and logging lists from this channel until going past the eof causes an error.
-- Each read begins at the byte immediately following the last byte of the preceding read.
repeat
log (read fref as list)
end repeat
on error
-- When the error occurs, close the access channel.
close access fref
end try