Tcl $argc and $argv variables

10,372

Solution 1

You appear to make two wrong assumptions here:

  • If a proc does not use a special argument args in its defintion (see below for more info), it accepts only the fixed number of arguments—exactly matching the number of parameters used in its definition. Each call is checked by the interpreter, and any call with invalid number of parameters will fail before reaching the procedure's code itself.

    See for yourself:

    % proc foo {a b c} {}
    % foo
    wrong # args: should be "foo a b c"
    % foo 1
    wrong # args: should be "foo a b c"
    % foo 1 2 3 4
    wrong # args: should be "foo a b c"
    % foo 1 2 3
    %
    

    In other words, just don't mess with trying to check the number of arguments passed to your proc: it's already checked by the interpreter by the time your procedure is called.

  • The argc and argv global variables control what's passed from the operating system to the Tcl interpreter program which is executing your Tcl script.

    That is, when you call something like

    $ tclsh myscript.tcl foo bar
    

    The variable named argc will contain 2 and argv will be set to the list containing two strings—"foo" and "bar".

    In other words, these variables have nothing to do with individual procedures.


Regarding the args special argument: if a procedure uses the word "args" for the last of its arguments or has it as its sole argument, then this argument is turned into a list which consumes any number (including zero) of actual arguments.

So you can do

proc foo {a b args} {}

and then your foo procedure can be called as both like foo 1 2 and foo 1 2 3 4 5 6 but not like foo x (because there's no value for the b formal argument).

Inside such a proc you use normal list commands (like llength and lindex) to inspect whatever is contained in args. For instance, the call foo 1 2 3 4 5 6 would set args to the same value you would obtain by calling [list 3 4 5 6].

Solution 2

The argc and argv variables are global variables (when they have any special meaning). Inside a procedure, they're not special at all unless you say:

global argc argv

or use the fully-qualified versions.

With your procedure, you will get an error message (generated by the procedure call machinery) unless you pass in the right number of arguments. You don't need to check yourself (unless you use formal parameters with defaults or the special args variable — note the spelling — at the end of the formal parameters.

To get the exact list of arguments passed in to your procedure, use:

set allArguments [info level 0]

You normally don't need it. You definitely don't need it when declaring your procedure like:

proc TestVerb { Data Data_txt } {
    ...
}
Share:
10,372
Flaxter
Author by

Flaxter

Updated on June 27, 2022

Comments

  • Flaxter
    Flaxter almost 2 years

    I'm kinda new to tcl but I have to write a proc that looks like this:

    proc TestVerb { Data Data_txt } {
    VERBATIM [format "// Data: $Data - $Data_txt"]
    if { $argc == 2} {
        VERBATIM {// SUCCESS //}
    else {
        exit 1
    }
    

    I call the proc like this: TestVerb Switch"This is used for..."

    The proc is in a different file and the proc call is in another one. They seem properly sourced because I get the desired output if I do not use $argc but once I use either $argv or $argc I get the following compilation error: Can't read $argv/$argc no such variable

    If I refer to this variables with $::argc and $::argv the result is not correct. $argv is empty and $argc is 0

  • Flaxter
    Flaxter over 9 years
    Hello, Thanks for the quick answer. The point is that proc will be used by other people and I need to check the number of arguments they have given to it and if it's not correct to exit; I've already tried using global argv argc But I still get incorrect output: argv <blank> argc 0