10. Subroutines


Accessing Subroutine Arguments

# Subroutines in Tcl are created with the [proc] command,
# which takes a list of formal parameters as its second
# argument.
# On activation, the parameters are bound to the "words"
# of the call (which may contain data, variable/subroutine
# names, executable expressions, etc).  This is a variant
# of call-by-name semantics.

proc hypotenuse {x y} {
   return [expr {sqrt($x*$x+$y*$y)}]   ;# Better still: use hypot()
set diag [hypotenuse 3 4]
# => 5.0

# Subroutines may have a variable number of 
# arguments, by using the special argument "args":

proc hypotenuse args {
   foreach {x y} $args break
   return [expr {hypot($x, $y)}]

# A subroutine can be applied to a list using [eval],
# which concatenates and then executes its arguments.

set a [list 3 4]
eval hypotenuse $a
# => 5.0

# It is possible to create local references
# to variables in other stack frames using
# [upvar], so the typical idiom for
# pass-by-reference is to pass the variable's
# name as argument, and [upvar] it:

set nums [list 1.4 3.5 6.7]
proc trunc-em {name} {
    upvar $name a
    set len [llength $a]
    for {set i 0} {$i < $len} {incr i} {
        lset a $i [expr {int([lindex $a $i])}]
trunc-em nums

Making Variables Private to a Function

Creating Persistent Private Variables

Determining Current Function Name

Passing Arrays and Hashes by Reference

Detecting Return Context

Passing by Named Parameter

Skipping Selected Return Values

Returning More Than One Array or Hash

Returning Failure

Prototyping Functions

Handling Exceptions

Saving Global Values

Redefining a Function

Trapping Undefined Function Calls with AUTOLOAD

Nesting Subroutines

Program: Sorting Your Mail