• Re: Is format incorrectly documented?

    From Ted Nolan @21:1/5 to [email protected] on Tue Aug 23 13:48:43 2022
    In article <[email protected]>,
    Cecil Westerhof <[email protected]> wrote:
    On https://www.tcl.tk/man/tcl8.5/TclCmd/format.html I see:
    If the % is followed by a decimal number and a $, as in “%2$d”,
    then the value to convert is not taken from the next sequential
    argument. Instead, it is taken from the argument indicated by the
    number, where 1 corresponds to the first arg. If the conversion
    specifier requires multiple arguments because of * characters in
    the specifier then successive arguments are used, starting with
    the argument given by the number. This follows the XPG3
    conventions for positional specifiers. If there are any positional
    specifiers in formatString then all of the specifiers must be
    positional.

    So I wrote:
    puts [format "ERROR:\
    %1$s \
    %1$s -once \
    %1$s -Tk" [file tail ${::argv0}]]

    But this gives:
    can't read "s": no such variable
    while executing
    "format "ERROR: %1$s %1$s -once %1$s -Tk"
    [file tail ${::argv0}]"

    Am I doing something wrong, or is the documentation incorrect?


    Shouldn't you be curly bracing your format string instead of
    double quoting so Tcl doesn't try to do variable expansion on it?
    --
    columbiaclosings.com
    What's not in Columbia anymore..

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Cecil Westerhof@21:1/5 to All on Tue Aug 23 15:33:57 2022
    On https://www.tcl.tk/man/tcl8.5/TclCmd/format.html I see:
    If the % is followed by a decimal number and a $, as in “%2$d”,
    then the value to convert is not taken from the next sequential
    argument. Instead, it is taken from the argument indicated by the
    number, where 1 corresponds to the first arg. If the conversion
    specifier requires multiple arguments because of * characters in
    the specifier then successive arguments are used, starting with
    the argument given by the number. This follows the XPG3
    conventions for positional specifiers. If there are any positional
    specifiers in formatString then all of the specifiers must be
    positional.

    So I wrote:
    puts [format "ERROR:\
    %1$s \
    %1$s -once \
    %1$s -Tk" [file tail ${::argv0}]]

    But this gives:
    can't read "s": no such variable
    while executing
    "format "ERROR: %1$s %1$s -once %1$s -Tk" [file tail ${::argv0}]"

    Am I doing something wrong, or is the documentation incorrect?

    --
    Cecil Westerhof
    Senior Software Engineer
    LinkedIn: http://www.linkedin.com/in/cecilwesterhof

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Cecil Westerhof on Tue Aug 23 14:28:19 2022
    Cecil Westerhof <[email protected]> wrote:
    On https://www.tcl.tk/man/tcl8.5/TclCmd/format.html I see:
    If the % is followed by a decimal number and a $, as in ?%2$d?,
    then the value to convert is not taken from the next sequential
    argument. Instead, it is taken from the argument indicated by the
    number, where 1 corresponds to the first arg. If the conversion
    specifier requires multiple arguments because of * characters in
    the specifier then successive arguments are used, starting with
    the argument given by the number. This follows the XPG3
    conventions for positional specifiers. If there are any positional
    specifiers in formatString then all of the specifiers must be
    positional.

    So I wrote:
    puts [format "ERROR:\
    %1$s \
    %1$s -once \
    %1$s -Tk" [file tail ${::argv0}]]

    But this gives:
    can't read "s": no such variable
    while executing
    "format "ERROR: %1$s %1$s -once %1$s -Tk" [file tail ${::argv0}]"

    Am I doing something wrong, or is the documentation incorrect?

    You put the format string inside double quotes (").

    Per rule 4 of "man Tcl", double quotes cause variable substitution to
    be performed (among other actions).

    Th $s in your format string is an attempt to substitute the contents of
    "s" into the string. But you have no variable "s" defined. Therefore
    the error of "can't read "s": no such variable".

    Either escape the $ so that variable expansion from double quotes is suppressed, or put the entire string inside curly braces ({}) which
    suppress variable and command substitutions, and almost all backslash
    escapes.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Cecil Westerhof@21:1/5 to [email protected] on Tue Aug 23 16:41:04 2022
    [email protected] (Ted Nolan <tednolan>) writes:

    In article <[email protected]>,
    Cecil Westerhof <[email protected]> wrote:
    On https://www.tcl.tk/man/tcl8.5/TclCmd/format.html I see:
    If the % is followed by a decimal number and a $, as in “%2$dâ€, >> then the value to convert is not taken from the next sequential
    argument. Instead, it is taken from the argument indicated by the
    number, where 1 corresponds to the first arg. If the conversion
    specifier requires multiple arguments because of * characters in
    the specifier then successive arguments are used, starting with
    the argument given by the number. This follows the XPG3
    conventions for positional specifiers. If there are any positional
    specifiers in formatString then all of the specifiers must be
    positional.

    So I wrote:
    puts [format "ERROR:\
    %1$s \
    %1$s -once \
    %1$s -Tk" [file tail ${::argv0}]]

    But this gives:
    can't read "s": no such variable
    while executing
    "format "ERROR: %1$s %1$s -once %1$s -Tk" >>[file tail ${::argv0}]"

    Am I doing something wrong, or is the documentation incorrect?


    Shouldn't you be curly bracing your format string instead of
    double quoting so Tcl doesn't try to do variable expansion on it?

    Yes, that is what I should have done. Now it works.
    Thanks.

    --
    Cecil Westerhof
    Senior Software Engineer
    LinkedIn: http://www.linkedin.com/in/cecilwesterhof

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)