Tcl Tutorial Lesson 12

Variations in proc arguments and return values

A procedure can be defined with a fixed number of required arguments (as was done with sum in the previous lesson, or it can have a variable number of arguments. An argument can also be defined to have a default value.

Variables can be defined with a default value by placing the variable name and the default within braces. For example:

proc justdoit {a {b 1} {c -1}} {
    ...
}

Since there are default values for the b and c arguments, you could call the procedure one of three ways: justdoit 10, which would set a to 10, and leave b set to its default 1, and c at -1. justdoit 10 20 would likewise set b to 20, and leave c to its default. Or call it with all three parameters set to avoid any defaults.

A proc will accept a variable number of arguments if the last declared argument is the word args. If the last argument to a proc argument list is args, then any arguments that aren't already assigned to previous variables will be assigned to args.

proc show_a_list {args} {
    set n 0
    foreach arg $args {
        puts "Argument $n: $arg"
        incr n
    }
}

show_a_list A B C D
puts ""
show_a_list E F

results in:

Argument 0: A
Argument 1: B
Argument 2: C
Argument 3: D

Argument 0: E
Argument 1: F

Note that if there is a variable other than args after a variable with a default, then the default will never be used. For example, if you declare a proc such as:

proc function { a {b 1} c} {...}

you will always have to call it with 3 arguments.

Tcl assigns values to a proc's variables in the order that they are listed in the command. If you provide 2 arguments when you call function they will be assigned to a and b, and Tcl will generate an error because c is undefined.

You can, however, declare other arguments that may not have values as coming after an argument with a default value. For example, this is valid:

proc example {required {default1 a} {default2 b} args} {...}

In this case, example requires one argument, which will be assigned to the variable required. If there are two arguments, the second arg will be assigned to default1. If there are 3 arguments, the first will be assigned to required, the second to default1, and the third to default2. If example is called with more than 3 arguments, all the arguments after the third will be assigned to args.


Example

The example procedure below is defined with three arguments. At least one argument must be present when example is called. The second argument can be left out, and in that case it will default to an empty string. By declaring args as the last argument, example can take a variable number of arguments.

Also note the use of the return statement to explicitly return a particular result.

proc example {first {second ""} args} {
    if {$second eq ""} {
        puts "There is only one argument and it is: $first"
        return 1
    } else {
        if {$args eq ""} {
            puts "There are two arguments - $first and $second"
            return 2
        } else {
            puts "There are many arguments:\n$first and $second and $args"
            return "many"
        }
    }
}

set count1 [example ONE]
set count2 [example ONE TWO]
set count3 [example ONE TWO THREE ]
set count4 [example ONE TWO THREE FOUR]

puts "The example was called with a varying number of arguments:"
puts "    $count1, $count2, $count3, and $count4"

  Resulting output
There is only one argument and it is: ONE
There are two arguments - ONE and TWO
There are many arguments - ONE and TWO and THREE
There are many arguments - ONE and TWO and THREE FOUR
The example was called with a varying number of arguments:
    1, 2, many, and many"