Search code examples
tclcommand-substitution

How do I prevent substitution before processing in TCL?


I'm calling a TCL procedure like this-

::f::abstract -procname my_proc -args "-arg1 $a -arg2 $b"

Now here $a itself is something like this-

"ping -c 1 10.1.1.$ip"

When I try to run this, $a is expanded, and it becomes-

-args "-arg1 ping -c 1 10.1.1.27 -arg2 a2"

This gives an error because now it appears we have additional arguments like -c.

What I want is to take in $a as as a whole, and later on expand it inside the procedure.

How do I do that?

I can't use {} brackets because I need variable substitution. I can't remove quotes because the outer quotes take in args.


Solution

  • Welcome to quoting horrors.

    If you expand it properly in the procedure, treat it like a proper list:

    ::f::abstract -procname my_proc -args [list -arg1 $a -arg2 $b]
    

    This gets passed to your proc exactly like you can expect: as four things:

    • the string -arg1
    • the list/script ping - c1 10.1.1.$ip
    • the string -arg2
    • the string <whatever $b expands to>

    Inside your proc, you will have to again eval your arg1's 'a' value, just as you expect (I hope, multiple evaluation is given in your structure here).

    proc ... args {
        array set options <defaults>
        array set options $args
        set a [uplevel 1 $options(-arg1)]
        ...
        # $a now has a useful value...
    }