- Save all variables
- Save all arrays
- Save all procedures
- Save all images
- Traverse and save the widget tree
proc save_state {} {
uplevel {
set fh [open $statefile w]
foreach v [info var] {
if [array exists $v] {
puts $fh "a $v = [array get $v]"
} else {
puts $fh "v $v = [set $v]"
}
}
close $fh
}
}
package require fileutil
# cuz I love this package (obv. you could open/close a file yourself)
proc restore_state {} {
uplevel {
fileutil::foreachLine l $::statefile {
if {[lindex $l 1] == "type"} {
continue
}
if {[lindex $l 0] == "a"} {
array set [lindex $l 1] [lrange $l 3 end]
# puts "setting a [lindex $l 1]"
} else {
set [lindex $l 1] [lrange $l 3 end]
# puts "setting v [lindex $l 1]"
}
}
puts "Done restoring session"
}
}Same stuff, but I like this better:
# save vars and arrays
proc save_state {} {
uplevel 1 {
set fh [open $::statefile w]
foreach v [info vars] {
if [array exists $v] {
puts $fh [list array set $v [array get $v]]
} else {
puts $fh [list set $v [set $v]]
}
}
close $fh
}
}
# restore
proc restore_state {} {
uplevel 1 {
source $::statefile
}
}LV 2009-Sep-16 There's a gotcha here that needs to be recognized. Dumping variables and then in a new process reading them back in might work, but depending on what the variable represents, the restore of the variable may not be useful.Take, for instance, this code:
set fd [open "/etc/passwd" "r"] set line [read $fd]If one blindly runs the save state type procedure, what one ends up is an fd that has a string value that is the equivalent of this script - however, the internal state of the file handle is not replicated, so any attempt (after restoring the saved state in a new process) to make use of $fd to read the next line of the password file will fail. Not only that, but the state of the password file itself may very well have changed so that even if one were able to dump the internal data structures and then attempted to reopen the file and position to the byte offset originally pointed to, the next read would not necessary represent a valid record.The idea of checkpoint/restart is a tough nut to crack. One has to carefully detail the contract for the save/restore so that the user doesn't think they are getting more than they actually are.
See also:
- fileutil (man page [2])
- envsave.tcl An attempt to save a running TclTk environment
- Dumping interpreter state

