Variations in proc arguments and return values

A proc can be defined with a set 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 within args. For example:

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

}

Since there are default arguments for the b and c variables, 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.

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.

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

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 - $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 $count1, $count2, $count3, and $count4 Arguments"