:TITLE: Learning the existence of commands and variables ? - info ;# ;# RCSID: $Header: /cvsroot/tcl/tcltutorial/original/Tcl27.lsn,v 1.1 2004/11/04 16:01:14 davidw Exp $ ;# Copyright (c) 1995 Clif Flynt ;# 9300 Fleming Rd. ;# Dexter, MI 48130 ;# clif@cflynt.com ;# See file "NOTICE" for licensing terms. ;# :LESSON_TEXT_START_LEVEL 0: The info command allows a Tcl program to obtain information from the Tcl interpreter about the current state of the interpreter. The next three lessons cover aspects of the info command.

This lesson covers the info subcommands that return information about which procs, variables, or commands are currently in existence in this instance of the interpreter. By using these subcommands you can determine if a variable or proc exists before you try to access it.

Info commands that return lists of visible commands and variables.

info commands ?pattern?
Returns a list of the commands that match pattern, using the string match rules. If pattern is not provided, a list of all commands is returned.
info exists varName
Returns 1 if varName exists as a variable in the current context, otherwise returns 0.
info globals ?pattern?
Returns a list of the global variables that match pattern, using the string match rules. If pattern is not provided, a list of all global variables is returned.
info locals ?pattern?
Returns a list of the local variables that match pattern, using the string match rules. If pattern is not provided, a list of all local variables is returned.
info procs ?pattern?
Returns a list of the procs that match pattern, using the string match rules. If pattern is not provided, a list of all procs is returned.
info vars ?pattern?
Returns a list of the variables that match pattern, using the string match rules. If pattern is not provided, a list of all variables is returned.
:TEXT_END: :LESSON_TEXT_START_LEVEL 1: The info command allows a Tcl program to obtain information from the Tcl interpreter about the current state of the interpreter. The next three lessons cover aspects of the info command.

This lesson covers the info subcommands that return information about which procs, variables, or commands are currently in existence in this instance of the interpreter. By using these subcommands you can determine if a variable or proc exists before you try to access it.

The example code shows how to use the info exists command to make an incr that will never return a no such variable error, since it checks to be certain that the variable exists before incrementing it.

Info commands that return lists of visible commands and variables.

info commands ?pattern?
Returns a list of the commands that match pattern, using the string match rules. If pattern is not provided, a list of all commands is returned.
info exists varName
Returns 1 if varName exists as a variable in the current context, otherwise returns 0.
info globals ?pattern?
Returns a list of the global variables that match pattern, using the string match rules. If pattern is not provided, a list of all global variables is returned.
info locals ?pattern?
Returns a list of the local variables that match pattern, using the string match rules. If pattern is not provided, a list of all local variables is returned.
info procs ?pattern?
Returns a list of the procs that match pattern, using the string match rules. If pattern is not provided, a list of all procs is returned.
info vars ?pattern?
Returns a list of the variables that match pattern, using the string match rules. If pattern is not provided, a list of all variables is returned.
:TEXT_END: :LESSON_TEXT_START_LEVEL 2: The Tcl interpreter has many tables of information that it keeps track of while the interpreter is executing. These tables include lists of all the procs and commands that have been defined, lists of global variables, and lists of variables that are visible to the current proc.

This lesson covers the info subcommands that return these lists of what procs, commands, and variables are available. By using these subcommands you can determine if a variable or proc exists before you try to access it.

For instance, consider what would happen if you tried to increment a variable that hadn't been defined yet. This can happen easily if you use the associative arrays to build a histogram from raw statistical data, for example.

The example code shows how to use the info exists command to make an incr that will never return a no such variable error, since it checks to be certain that the variable exists before incrementing it.

Run the example, and look at the output while you read this description of the code.

The first proc is the safeIncr proc. It takes two arguments, the second of which defaults to a value of 1. The first argument is the name of a variable that may exist in the calling program. These are the same arguments that you would use when calling the normal incr command.

After using the upvar command to link the local scope of the variable to the level above, info exists is called to determine if the variable exists. If it exists, then incr is called. If info exists returns false, then the variable is initialized to the increment value.

The next line shows how you can use the info procs command to find out if a proc exists before you invoke it. Info procs will return a list of procs that match a string, or a list of all procs if there is no second argument.

After this are several lines that demonstrate safeIncr working.

Next, info vars and info globals are used to list all the variables that are available in the current scope. These lists are identical because all variables at the top level are global.

Next, info procs is used to test for a proc that hasn't been defined yet.

Localproc shows the differences in variables that are defined within a procedure. Only the loc1 and loc2 are local to the proc, while argv is available because it is declared as a global.

If argv were not declared global, but were just used in this function, a local argv variable would be created for use inside this proc. This local argv would not have the value that the global argv has, and any modifications made to argv would be lost when this proc returned.

After localproc is defined, info procs is used again to show that the proc now exists.

Finally, localproc is called, and the variables visible from inside a proc are displayed.

Info commands that return lists of visible commands and variables.

info commands ?pattern?
Returns a list of the commands that match pattern, using the string match rules. If pattern is not provided, a list of all commands is returned.
info exists varName
Returns 1 if varName exists as a variable in the current context, otherwise returns 0.
info globals ?pattern?
Returns a list of the global variables that match pattern, using the string match rules. If pattern is not provided, a list of all global variables is returned.
info locals ?pattern?
Returns a list of the local variables that match pattern, using the string match rules. If pattern is not provided, a list of all local variables is returned.
info procs ?pattern?
Returns a list of the procs that match pattern, using the string match rules. If pattern is not provided, a list of all procs is returned.
info vars?pattern?
Returns a list of the variables that match pattern, using the string match rules. If pattern is not provided, a list of all variables is returned.
:TEXT_END: :CODE_START: ;# ;# safeIncr checks for a variable's existence before ;# it tries to increment it. If the variable does not exist, ;# it is initialized and returned. proc safeIncr {val {amt 1}} { upvar $val v if {[info exists v]} { incr v $amt} else { set v $amt } } ;# ;# Check that the safeIncr proc exists before invoking it. if {[info procs safeIncr] == "safeIncr"} { safeIncr a } puts "After calling SafeIncr with a non existent variable: $a" set a 100 safeIncr a puts "After calling SafeIncr with a variable with a value of 100: $a" safeIncr b -3 puts "After calling safeIncr with a non existent variable by -3: $b" set b 100 safeIncr b -3 puts "After calling safeIncr with a variable whose value is 100 by -3: $b" puts "\nThese variables have been defined: [lsort [info vars]]" puts "\nThese globals have been defined: [lsort [info globals]]" ;# ;# Check for the existence of localproc ;# set exist [info procs localproc]; if {$exist == ""} { puts "\nlocalproc does not exist at point 1" } proc localproc {} { global argv; set loc1 1; set loc2 2; puts "\nLocal variables accessible in this proc are: [lsort [info locals]]" puts "\nVariables accessible from this proc are: [lsort [info vars]]" puts "\nGlobal variables visible from this proc are: [lsort [info globals]]" } set exist [info procs localproc]; if {$exist != ""} { puts "localproc does exist at point 2" } localproc; :TEXT_END: