Reputation: 2585
In TCL the way to make a parameter optional is to give it a default value. I don't know if there are any other ways too. e.g
proc my_func {a b c {d 10} {e 11} {f 12}} {
...
}
Now in the above example the parameters a, b and c are compulsory. The parameters d, e and f are optional. Is there another way to create optional parameters?
I am in a situation where I need to create a parameter that can be called from a TCL terminal (in Xilinx Vivado) which has some optional parameters. The user decide to pass a few or all of the optional parameters or none at all. The problem is that, when using positional argument passing, it is impossible to tell TCL which optional parameter we are passing to it. What is the solution to this? e.g
my_func 1 2 3 4 5 6
shall call the my_func with values a=1, b=2, c=3, d=4, e=5 and f=6. Also,
my_func 1 2 3 4
shall call my_func with values a=1, b=2, c=3 and d=4 and the e, f left at their default values. However, I might need to do something like this
my_func 1 2 3 100
where I am passing 100 to f and leave c and d at default value. But the above stament will set d to 100 instead and leave e and f at their default values.
What is the solution since I can clearly not use the positional argument technique here.
Upvotes: 0
Views: 210
Reputation: 3434
The below is a minor variation to the solutions already suggested. By using dict with
, on can unpack the dictionary content into the proc-local scope as variables:
proc my_func {a b c args} {
set () [dict merge {(d) 10 (e) 11 (f) 12} $args]
dict with () {}
puts "a = $a"
puts "b = $b"
puts "c = $c"
puts "d = $(d)"
puts "e = $(e)"
puts "f = $(f)"
}
Some remarks:
()
.dict with
will unpack the so-named keys into that array: (e)
, (f)
, ...$
syntax: $(e)
, $(f)
, ...Watch:
my_func 1 2 3
my_func 1 2 3 (e) 100 (d) 200
Yields:
a = 1
b = 2
c = 3
d = 10
e = 11
f = 12
a = 1
b = 2
c = 3
d = 200
e = 100
f = 12
Upvotes: 1
Reputation: 246744
A readable way to design the function is to do it Tk style: use -d 100
options:
proc my_func {a b c args} {
set opts [dict merge {-d 10 -e 11 -f 12} $args]
puts "a = $a"
puts "b = $b"
puts "c = $c"
puts "d = [dict get $opts -d]"
puts "e = [dict get $opts -e]"
puts "f = [dict get $opts -f]"
}
Then when you use them, you can specify them in any order:
% my_func
wrong # args: should be "my_func a b c ?arg ...?"
% my_func 1 2 3
a = 1
b = 2
c = 3
d = 10
e = 11
f = 12
% my_func 1 2 3 -e 100 -d 200
a = 1
b = 2
c = 3
d = 200
e = 100
f = 12
Upvotes: 2
Reputation: 1863
If the final argument in your proc definition is literally args
, then the remaining arguments (if any) are collected in a list.
This proc demonstrates how d,e,f can be optional. The optional arguments are included as a {name value} pair.
proc my_func {a b c args} {
set defaults {d 10 e 11 f 12}
foreach {var_name var_value} $defaults {
set $var_name $var_value
}
foreach arg $args {
set [lindex $arg 0] [lindex $arg 1]
}
puts "a:$a b:$b c:$c d:$d e:$e f:$f"
}
tcl8.6.8> my_func 1 2 3
a:1 b:2 c:3 d:10 e:11 f:12
tcl8.6.8> my_func 1 2 3 {d 5} {e 8} {f 99}
a:1 b:2 c:3 d:5 e:8 f:99
tcl8.6.8> my_func 1 2 3 {f 99}
a:1 b:2 c:3 d:10 e:11 f:99
Upvotes: 1