There seems to be an inconsitent behavior from traces.
While a read or write trace propagates an error, unset
does not. Is this the intended behavor?
the script below returns in tcl 8.3.3 and 8.4.2:
===================================================
set x 1: error can't set "x": trying to w on x
set x: error can't read "x": trying to r on x
unset x: no error
===================================================
I would like to see
===================================================
set x 1: error can't set "x": trying to w on x
set x: error can't read "x": trying to r on x
unset x: error can't unset "x": trying to u on x
===================================================
Best regards
-gustaf neumann
proc my_check {var sub op} {
error "trying to $op on $var"
}
trace variable x rwu my_check
foreach cmd {{set x 1} {set x} {unset x}} {
if {[catch $cmd msg]} {
puts "$cmd: error $msg"
} else {
puts "$cmd: no error"
}
}
That's exactly what the docs specify will happen.
http://www.tcl.tk/man/tcl8.4/TclCmd/trace.htm#M18
Note that the unset trace fires *after* the variable is unset,
so it's too late to stop it. (Same is true with a write trace
- even if you throw an error the variable has already been written)
For more info on tracing check out http://wiki.tcl.tk/trace
Bruce
He requested the error (after the action) to be propagated.
That is: the [unset] would unset the var, then throw an error.
The docs do not define a special behaviour for this case.
The added line to his example shows, that the trace *does* get fired,
but its error is not propagated, as Gustaf (rightly, imho) complained.
> For more info on tracing check out http://wiki.tcl.tk/trace
this url doesn't seem to mention exceptions in traces, at all.
--
Nichts ist schlimmer als zu wissen, wie das Unheil sich entwickelt,
und voll Ohnmacht zusehn muessen - das macht mich voellig krank...
-- (Musical Elisabeth; "Die Schatten werden laenger")
> That is: the [unset] would unset the var, then throw an error.
> The docs do not define a special behaviour for this case.
incorrect, if you read the trace manpage more carefully you'll see that
it says:
Any errors in unset traces are ignored.
Cheers,
Daniel
--
** Daniel A. Steffen ** "And now to something completely
** Dept. of Mathematics ** different" Monty Python
** Macquarie University ** <mailto:ste...@maths.mq.edu.au>
** NSW 2109 Australia ** <http://www.maths.mq.edu.au/~steffen/>
What was the reason for this behaviour (ignoring these errors) ?
>
> That's exactly what the docs specify will happen.
>
> http://www.tcl.tk/man/tcl8.4/TclCmd/trace.htm#M18
>
sure, you are right, the man page says:
"... Any errors in unset traces are ignored."
but this alone does not make it a feature.
> Note that the unset trace fires *after* the variable is unset,
> so it's too late to stop it. (Same is true with a write trace
> - even if you throw an error the variable has already been written)
i am aware of this. In principle, the trace callback can undo the behavior
of the command by keeping a shadow instance of the variable and
restore it. But this was not my intention.
i wanted to raise an error, whenever the specified
variable is read/written/unset from a certain context. This works
nicely for read/write traces, but not for unset. It is certianly
possible, to redfeine/rename the tcl undo command, to sideeffect from the
unset callback routine, and to check from the own unset command, whether
the side effect happened, but this does not make me very happy.
what is the reason for ignoring the resultcode from the callback
routine? is it due to the fact that the same c-routine is used
during automatic unsets on proc exists?
greetings
-gustaf
Gustaf Neumann wrote:
> Bruce B Hartweg <Bruce_B...@raytheon.com> wrote in message news:<3E9EDCB1...@raytheon.com>...
>
> >
> > That's exactly what the docs specify will happen.
> >
> > http://www.tcl.tk/man/tcl8.4/TclCmd/trace.htm#M18
> >
>
> sure, you are right, the man page says:
> "... Any errors in unset traces are ignored."
>
> but this alone does not make it a feature.
not a feature neccessarily, but not a bug either.
>
>
> > Note that the unset trace fires *after* the variable is unset,
> > so it's too late to stop it. (Same is true with a write trace
> > - even if you throw an error the variable has already been written)
>
> i am aware of this. In principle, the trace callback can undo the behavior
> of the command by keeping a shadow instance of the variable and
> restore it. But this was not my intention.
>
> i wanted to raise an error, whenever the specified
> variable is read/written/unset from a certain context. This works
> nicely for read/write traces, but not for unset. It is certianly
> possible, to redfeine/rename the tcl undo command, to sideeffect from the
> unset callback routine, and to check from the own unset command, whether
> the side effect happened, but this does not make me very happy.
>
> what is the reason for ignoring the resultcode from the callback
> routine? is it due to the fact that the same c-routine is used
> during automatic unsets on proc exists?
I don't knowe for sure, but my guess would be that since unsetting
a variable may be done automaticly (not just an explicit "unset" command)
(i.e. a return from a proc unsets local vars, deleteing namespaces will
unset vars, etc) then where woudl the error be propagated to?
Bruce
what happens in other cases, when an error is encountered? The proc
ends with an error state..... I do not see what's wrong with the
scenario, where a programmer
- sets an unset trace on a local variable,
- which is automatically unset, and
- the unset triggers an error,
- which triggers an error of the proc.
It is better than silently ignoring the error, actually every error
triggered from the unset callback
-gustaf
proc my_check {var sub op} {this is a tcl command raising an error}