简体   繁体   中英

TCL how protect from override?

I have 2 scripts

listing file 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:

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

How protect value $c in 1.mac from overriding in 2.mac?

changing variable name in 2.mac not good for me

Tcl normally doesn't protect you against that. 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 ::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.

For strong isolation, create an interpreter (with interp create ) and source the script within it. 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.

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. Standard commands are known, as are procedures using them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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