简体   繁体   English

TCL如何防止覆盖?

[英]TCL how protect from override?

I have 2 scripts我有2个脚本

listing file 1.mac:清单文件1.mac:

proc setByUpvar { value } {
    return [expr {$value *2}]
}
        
set ex_result [catch {
    set c [setByUpvar 12 ]
    echo "$c [argument -this]"
    sym run macro -file C:/Custom/2.mac 
    echo "$c [argument -this]"
} errors]

listing file 2.mac:清单文件2.mac:

proc setByUpvar { value } {
    return [expr {$value *2}]
}
        
set ex_result [catch {
    set c [setByUpvar 4]    
    echo "$c [argument -this]"
} errors]

first macro calls second macro第一个宏调用第二个宏

after run file 2.mac, in 1.mac variable $c has value from 2.mac运行文件 2.mac 后,在 1.mac 中变量 $c 的值来自 2.mac

How protect value $c in 1.mac from overriding in 2.mac?如何保护 1.mac 中的 $c 值不被 2.mac 覆盖?

changing variable name in 2.mac not good for me在 2.mac 中更改变量名对我不利

Tcl normally doesn't protect you against that. Tcl 通常不会保护您免受这种情况的影响。 Script files are not normally isolated from each other.脚本文件通常不会相互隔离。 By policy/design.通过策略/设计。

For light isolation, you can put the code in the script files inside a namespace eval :对于轻度隔离,您可以将代码放在namespace eval内的脚本文件中:

namespace eval ::mac1 {
    proc setByUpvar { value } {
        return [expr {$value *2}]
    }

    # Setting variables directly at the namespace-eval level is a bit tricky so avoid that
    proc task {} {
        variable ex_result
        variable errors
        variable c
        set ex_result [catch {
            set c [setByUpvar 12 ]
            echo "$c [argument -this]"
            sym run macro -file C:/Custom/2.mac 
            echo "$c [argument -this]"
        } errors]
    }

    task
}

In this case, the code can see the other variables, but not by default.在这种情况下,代码可以看到其他变量,但默认情况下看不到。 It has to go looking elsewhere.它必须到 go 寻找其他地方。

For strong isolation, create an interpreter (with interp create ) and source the script within it.对于隔离,创建一个解释器( source interp create )并在其中获取脚本。 Interpreters can't reach other interpreters (except under very defined circumstances that don't matter here) so the code really can't have any impact on the other script.口译员无法联系到其他口译员(除非在非常明确的情况下,这里无关紧要),因此代码实际上不会对其他脚本产生任何影响。 However, you might lose access to special commands and so on;但是,您可能无法访问特殊命令等; isolation really is isolation.隔离真的是隔离。 And this is a comparatively expensive option.这是一个相对昂贵的选择。 (Not as expensive as starting another process.) (不像开始另一个过程那么昂贵。)

set isolated [interp create]
interp eval $isolated [list source 1.mac]
interp delete $isolated

You can strengthen the isolation by making the interpreter be safe (disables OS access) and you can weaken it by poking callback holes with interp alias to provide the special commands you actually want.您可以通过使解释器安全(禁用操作系统访问)来加强隔离,并且可以通过使用interp alias戳回调漏洞以提供您实际需要的特殊命令来削弱它。

proc myFoo args {
    puts "this is a callback in the master interpreter: arguments=$args"
}
interp alias $isolated foo {} myFoo

How any of this will interact with the non-standard Tcl commands you're running ( sym , argument ) is a complete unknown to me.我完全知道这将如何与您正在运行的非标准 Tcl 命令( symargument )交互。 Standard commands are known, as are procedures using them.标准命令是已知的,使用它们的过程也是已知的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM