The return value is detmined by the last command to take place.
Each and every command returns a value. In many cases, thsi value is invisible to normal Tcl. Take the following examples, and I will show you what they return.
Code: Select all
proc hand {} {
return 1
}
proc test1 {} {
set a [hand]
return $a
}
proc test2 {} {
return [hand]
}
proc test3 {} {
hand
}
Test1, 2 & 3 all return 1
Test1 is obvious to how it works, and test2 is a simplified version.
In test3, the command "hand" is called. The return value (no the return code) is set to 1. Once it comes back down into test3, the return value buffer is not cleared (the return value buffer is cleared at the start of calling a command). Because there is still a value in the buffer, it is also returned by test3.
The "set" command, returns that value of the variable passed, or the value it has just been set to. In other words, the reason what your catch stament is called.
In your first catch block, you have the "close" command. This doesn't return any value at all. As noted above, the buffer is cleared at the start of a command, and because it isn't filled again by the close command, there is nothing in the rturn value.
The way to your script working, is not to test the value of the err_msg variable. It is to test the value returned from the catch command. It returns 1 on error, 0 on all ok (TCL_OK).
EG
Code: Select all
proc create_file_from_list {filename data_list} {
if {[catch {
set fc [open $filename w]
puts -nonewline $fc $data_list
close $fc
} err_msg]} {
return [list -1 "Error while writing file"]
} else {
return [list 0]
}
}