SemiCode
SemiCode

Reputation: 35

pass variable from lower proc to upper proc in Tcl

I have the following code and it prints the same value of variable c in the inner loop.

global c

proc one { a c } {
    for {set i $a} {$i < 10} {incr i} {
        two $c
    }
}

proc two { c } {
     incr c
     puts "Value of c is $c"
}

When I run it with the following inputs:

two 0 3

it prints 10 times "Value of c is 4" instead of keeping increasing the value of c inside the loop from 4 to 13.

The problem is the value of c from proc two is not passing up again to the for loop and it takes the same value from proc one parser c as 3. How can I get the desired output?

Upvotes: 0

Views: 893

Answers (2)

mrcalvin
mrcalvin

Reputation: 3434

I am aware that the following does not reflect the OP's actual question, this is more like a suggestion for re-considering the design. Why use "by reference" parameter passing to begin with, here?

Why not simply stick with a functional style using return and continuously updating the proc-local variable c within the loop body's script?

proc one { a c } {
    for {set i $a} {$i < 10} {incr i} {
        set c [two $c] ;# <= note: passing 'c' by value
        puts "Value of c is $c"
    }
}

proc two { c_value } {
    incr c_value
    return $c_value
}

one 0 3

This will make two re-usable in different contexts, by different callers. Also: It can be easily extended to multiple return values, variable updates using lassign in the caller's context (one).

Upvotes: 0

rtx13
rtx13

Reputation: 2610

It sounds like you want to pass the variable c from proc one to proc two by reference so that changes to the value of the variable are reflected back in the caller.

One way to accomplish this in tcl is to pass the name of the variable, and use the upvar command, as follows:

proc one { a c } {
    for {set i $a} {$i < 10} {incr i} {
        two c  ;# <= note: passing 'c' by name, not by value
    }
}

proc two { c_name } {
    upvar $c_name c  ;# <= note: c in this proc is using callers variable
    incr c
    puts "Value of c is $c"
}

one 0 3

The above produces the following output:

Value of c is 4
Value of c is 5
Value of c is 6
Value of c is 7
Value of c is 8
Value of c is 9
Value of c is 10
Value of c is 11
Value of c is 12
Value of c is 13

Upvotes: 2

Related Questions