在取消设置跟踪变量时触发错误 [英] Triggering an error on unsetting a traced variable

查看:21
本文介绍了在取消设置跟踪变量时触发错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一些只读变量,以便与在安全 interp 中评估的代码一起使用.使用 trace,我可以在尝试设置它们时生成错误,但在使用 unset 时不会:

I'm trying to create some read-only variables to use with code evaluated in a safe interp. Using trace, I can generate an error on attempts to set them, but not when using unset:

% set foo bar
bar
% trace add variable foo {unset write} {apply {{var _ op} { error "$var $op trace triggered" }}}
% set foo bar
can't set "foo": foo write trace triggered
% unset foo
% 

确实,我最终注意到了文档甚至顺便说:

Indeed, I eventually noticed the documentation even says in passing:

忽略未设置跟踪中的任何错误.

Any errors in unset traces are ignored.

使用不同的return 代码,包括自定义数字,它们全部似乎都被忽略了.它也不会触发 interp bgerror 处理程序.有没有其他方法可以在尝试取消设置特定变量时引发错误?

Playing around with different return codes, including custom numbers, they all seem to be ignored. It doesn't trigger an interp bgerror handler either. Is there any other way to raise an error for an attempt to unset a particular variable?

推荐答案

确实没有.关键问题是,有时 Tcl 将取消设置一个变量,而该变量真的将被删除,因为它的包含结构(命名空间、堆栈框架或对象,最终是一个解释器)也正在被删除.变量在那时就注定了,用户代码无法阻止它(当然,从不从跟踪中返回的可怕方法除外,这会无限推迟死亡并使一切都处于奇怪的状态;不要那样做).根本无处可恢复变量.命令删除痕迹也有同样的问题;它们也可能被解雇,因为它们的存储正在消失.(TclOO 析构函数对此有更多的保护;它们尽量不丢失错误——甚至将它们放入 interp bgerror 作为最后的手段——但在某些边缘情况下仍然可以.)

There really isn't. The key problem is that there are times when Tcl is going to unset a variable when that variable really is going to be deleted because its containing structure (a namespace, stack frame or object, and ultimately an interpreter) is also being deleted. The variable is doomed at that point and user code cannot prevent it (except by the horrible approach of never returning from the trace, of course, which infinitely postpones the death and puts everything in a weird state; don't do that). There's simply nowhere to resurrect the variable to. Command deletion traces have the same issue; they too can be firing because their storage is vanishing. (TclOO destructors are a bit more protected against this; they try to not lose errors — there's even pitching them into interp bgerror as a last resort — but still can in some edge cases.)

此外,API 中目前没有任何内容允许错误消息从删除命名空间或调用框架的过程中冒出来.我认为这是可以解决的(它需要更改一些公共 API),但出于充分的理由,我认为删除仍然必须发生,尤其是对于堆栈帧.此外,我不确定当您删除包含两个未设置跟踪变量的名称空间时会发生什么,这些变量的跟踪都报告错误.错误应该是什么?我真的不知道.(我知道最终结果必须是命名空间仍然消失了,FWIW,但细节很重要,我不知道它们应该是什么.)

What's more, there's currently nothing in the API to allow an error message to bubble out of the process of deleting a namespace or call frame. I think that would be fixable (it would require changing some public APIs) but for good reasons I think the deletion would still have to happen, especially for stack frames. Additionally, I'm not sure what should happen when you delete a namespace containing two unset-traced variables whose traces both report errors. What should the error be? I really don't know. (I know that the end result has to be that the namespace is still gone, FWIW, but the details matter and I have no idea what they should be.)

这篇关于在取消设置跟踪变量时触发错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆