Version 0 of Persistent arrays

Updated 2002-06-03 08:48:03

Richard Suchenwirth 2002-05-30 - Large data (e.g. a simple database) are in Tcl often stored in arrays. You can load array contents from files, and you can store them to files, so the data persists between sessions. Here is some code that "ties" an array to a file, so initially the array is "loaded" from the file, and changes to the array are reflected in the file too. This is done by opening it for appending, writing the changed data, and closing it - possibly slow, but very robust. If you don't give a filename, it is made up of the array name and the extension ".txt".

A special application for this is event logging: register a global persistent array once and assign to it, for instance with a telling key like clock seconds for each event:

 persistentArray log mylogfile
 ...
 set log([clock seconds]) "$this happened."
 ...
 set log([clock seconds]) "$that happened."

When later examining the logfile, you can reconstruct the date and time of the events with clock format. The disadvantage against pure file logging is that all event messages remain in the array.

 proc persistentArray {arrName {filename {}}} {
    upvar 1 $arrName arr
    array set arr {} ;# to make sure it exists, and is an array
    if {$filename==""} {set filename $arrName.txt}
    set filename [file join [pwd] $filename]
    if [file exists $filename] {
        set fp [open $filename]
        array set arr [read $fp]
        close $fp
    }
    uplevel 1 [list trace var $arrName wu [list persist'save $filename]]
 }
 proc persist'save {filename arrName el op} {
    upvar 1 $arrName arr
    switch -- $op {
        w {set value $arr($el)}
        u {set value {}}
    }
    set    fp [open $filename a]
    puts  $fp [list $el $value]
    close $fp
 }