• misunderstaning of switch command

    From Mark Summerfield@m.n.summerfield@gmail.com to comp.lang.tcl on Tue Jun 24 08:23:45 2025
    From Newsgroup: comp.lang.tcl

    I have a switch command which is doing something I don't expect but I
    don't understand what I've done wrong. In this example the default is
    always executed but I expect the case before that to be executed.

    const UNCOMPRESSED U
    const ZLIB_COMPRESSED Z
    const SAME_AS_PREV =
    set filename somefile.txt
    set action "added"
    set kind Z
    switch $kind {
    $::SAME_AS_PREV { puts "unchanged \"$filename\"" }
    $::UNCOMPRESSED { puts "$action \"$filename\"" }
    $::ZLIB_COMPRESSED { puts "$action \"$filename\" (zlib
    compressed)" }
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }
    }

    What am I doing wrong?
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Harald Oehlmann@wortkarg3@yahoo.com to comp.lang.tcl on Tue Jun 24 10:37:08 2025
    From Newsgroup: comp.lang.tcl

    Am 24.06.2025 um 10:23 schrieb Mark Summerfield:
    I have a switch command which is doing something I don't expect but I
    don't understand what I've done wrong. In this example the default is
    always executed but I expect the case before that to be executed.

    const UNCOMPRESSED U
    const ZLIB_COMPRESSED Z
    const SAME_AS_PREV =
    set filename somefile.txt
    set action "added"
    set kind Z
    switch $kind {
    $::SAME_AS_PREV { puts "unchanged \"$filename\"" }
    $::UNCOMPRESSED { puts "$action \"$filename\"" }
    $::ZLIB_COMPRESSED { puts "$action \"$filename\" (zlib
    compressed)" }
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }
    }

    What am I doing wrong?

    Nothing wrong. Tcl is just different, sorry for that.

    The "{" always avoids expansion of variables and commands. If you want
    to use variables in the switch, you have to avoid the "{".

    switch -exact -- $kind [list\
    $::SAME_AS_PREV { puts "unchanged \"$filename\"" }\
    $::UNCOMPRESSED { puts "$action \"$filename\"" }
    $::ZLIB_COMPRESSED { puts "$action \"$filename\" (zlib
    compressed)" }\
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }\
    ]

    Nevertheless, this is no fun on the quoting level (backslashes at the
    end etc). In addition, you have to take care, when the variable
    expansion happens. This might be tricky.

    I personally would write it like that:

    switch -exact -- $kind {
    = { # SAME_AS_PREV
    puts "unchanged \"$filename\""
    }
    U { # UNCOMPRESSED
    puts "$action \"$filename\""
    }
    Z { # ZLIB_COMPRESSED
    puts "$action \"$filename\" (zlib compressed)"
    }
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }
    }

    Harald

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mark Summerfield@m.n.summerfield@gmail.com to comp.lang.tcl on Tue Jun 24 08:46:57 2025
    From Newsgroup: comp.lang.tcl

    On Tue, 24 Jun 2025 10:37:08 +0200, Harald Oehlmann wrote:

    Am 24.06.2025 um 10:23 schrieb Mark Summerfield:
    I have a switch command which is doing something I don't expect but I
    don't understand what I've done wrong. In this example the default is
    always executed but I expect the case before that to be executed.

    const UNCOMPRESSED U const ZLIB_COMPRESSED Z const SAME_AS_PREV =
    set filename somefile.txt set action "added"
    set kind Z switch $kind {
    $::SAME_AS_PREV { puts "unchanged \"$filename\"" }
    $::UNCOMPRESSED { puts "$action \"$filename\"" }
    $::ZLIB_COMPRESSED { puts "$action \"$filename\" (zlib
    compressed)" }
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }
    }

    What am I doing wrong?

    Nothing wrong. Tcl is just different, sorry for that.

    The "{" always avoids expansion of variables and commands. If you want
    to use variables in the switch, you have to avoid the "{".

    switch -exact -- $kind [list\
    $::SAME_AS_PREV { puts "unchanged \"$filename\"" }\
    $::UNCOMPRESSED { puts "$action \"$filename\"" }
    $::ZLIB_COMPRESSED { puts "$action \"$filename\" (zlib compressed)" }\
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }\
    ]

    Nevertheless, this is no fun on the quoting level (backslashes at the
    end etc). In addition, you have to take care, when the variable
    expansion happens. This might be tricky.

    I personally would write it like that:

    switch -exact -- $kind {
    = { # SAME_AS_PREV
    puts "unchanged \"$filename\""
    }
    U { # UNCOMPRESSED
    puts "$action \"$filename\""
    }
    Z { # ZLIB_COMPRESSED
    puts "$action \"$filename\" (zlib compressed)"
    }
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }
    }

    Harald

    Thanks that works great.

    Bit of a disinsentive to use consts though!
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Harald Oehlmann@wortkarg3@yahoo.com to comp.lang.tcl on Tue Jun 24 10:58:17 2025
    From Newsgroup: comp.lang.tcl

    Am 24.06.2025 um 10:46 schrieb Mark Summerfield:
    On Tue, 24 Jun 2025 10:37:08 +0200, Harald Oehlmann wrote:

    Am 24.06.2025 um 10:23 schrieb Mark Summerfield:
    I have a switch command which is doing something I don't expect but I
    don't understand what I've done wrong. In this example the default is
    always executed but I expect the case before that to be executed.

    const UNCOMPRESSED U const ZLIB_COMPRESSED Z const SAME_AS_PREV =
    set filename somefile.txt set action "added"
    set kind Z switch $kind {
    $::SAME_AS_PREV { puts "unchanged \"$filename\"" }
    $::UNCOMPRESSED { puts "$action \"$filename\"" }
    $::ZLIB_COMPRESSED { puts "$action \"$filename\" (zlib
    compressed)" }
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }
    }

    What am I doing wrong?

    Nothing wrong. Tcl is just different, sorry for that.

    The "{" always avoids expansion of variables and commands. If you want
    to use variables in the switch, you have to avoid the "{".

    switch -exact -- $kind [list\
    $::SAME_AS_PREV { puts "unchanged \"$filename\"" }\
    $::UNCOMPRESSED { puts "$action \"$filename\"" }
    $::ZLIB_COMPRESSED { puts "$action \"$filename\" (zlib
    compressed)" }\
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }\
    ]

    Nevertheless, this is no fun on the quoting level (backslashes at the
    end etc). In addition, you have to take care, when the variable
    expansion happens. This might be tricky.

    I personally would write it like that:

    switch -exact -- $kind {
    = { # SAME_AS_PREV
    puts "unchanged \"$filename\""
    }
    U { # UNCOMPRESSED
    puts "$action \"$filename\""
    }
    Z { # ZLIB_COMPRESSED
    puts "$action \"$filename\" (zlib compressed)"
    }
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }
    }

    Harald

    Thanks that works great.

    Bit of a disinsentive to use consts though!

    Great, that it works for you.

    If I want to compare something with multiple variables, I would use an
    if chain:

    if {$kind eq $::SAME_AS_PREV} {
    puts "unchanged \"$filename\""
    } else if {$kind eq $::UNCOMPRESSED} {
    puts "$action \"$filename\""
    } else if {$kind eq $::ZLIB_COMPRESSED} {
    puts "$action \"$filename\" (zlib >> compressed)"
    } else {
    puts "!!!!!!!! UNEXPECTED !!!!!!!!"
    }

    The "if" command takes his first argument and passes it to "expr".
    Then, eval will do the variable expansion.
    This does not happen with "switch".

    I never used const. But its use may help for clarity.

    Harald

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Harald Oehlmann@wortkarg3@yahoo.com to comp.lang.tcl on Tue Jun 24 11:08:24 2025
    From Newsgroup: comp.lang.tcl

    Sorry, typo in my last post:

    The "if" command takes his first argument and passes it to "expr".
    Then, eval will do the variable expansion.

    Correct:
    Then, expr will do the variable expansion.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Alan Grunwald@nospam.nurdglaw@gmail.com to comp.lang.tcl on Tue Jun 24 11:44:10 2025
    From Newsgroup: comp.lang.tcl

    On 24/06/2025 10:08, Harald Oehlmann wrote:
    Sorry, typo in my last post:

    The "if" command takes his first argument and passes it to "expr".
    Then, eval will do the variable expansion.

    Correct:
    Then, expr will do the variable expansion.


    Just one additional trick for a Tcl newbie to consider...

    The OP had several lines like

    $::SAME_AS_PREV { puts "unchanged \"$filename\"" }

    which have now morphed (typically) into

    if {$kind eq $::SAME_AS_PREV} {
    puts "unchanged \"$filename\""

    I have got into the habit of using the [format] command to build strings
    that have fixed and variable parts - it's kind of analagous to sprintf
    in C. This would lead me to change the output command to

    puts [format {unchanged "%s"} $filename]

    I believe it's easier to make out what's going on without all the
    backslashes that are otherwise needed around the quotes that surround
    the filename. (You can't exchange the outer quotes for curly brackets
    because that would prevent the Tcl interpreter from expanding $filename.]

    Hope you find this helpful.

    Alan
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Schelte@nospam@wanadoo.nl to comp.lang.tcl on Tue Jun 24 12:53:57 2025
    From Newsgroup: comp.lang.tcl

    On 24/06/2025 10:23, Mark Summerfield wrote:
    I have a switch command which is doing something I don't expect but I
    don't understand what I've done wrong. In this example the default is
    always executed but I expect the case before that to be executed.

    const UNCOMPRESSED U
    const ZLIB_COMPRESSED Z
    const SAME_AS_PREV =
    set filename somefile.txt
    set action "added"
    set kind Z
    switch $kind {
    $::SAME_AS_PREV { puts "unchanged \"$filename\"" }
    $::UNCOMPRESSED { puts "$action \"$filename\"" }
    $::ZLIB_COMPRESSED { puts "$action \"$filename\" (zlib
    compressed)" }
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }
    }

    What am I doing wrong?

    Switch allows for two different ways to specify the pattern/body pairs:
    As as a single argument or as individual arguments. If you want the
    patterns to be in variables (or consts) you may prefer the latter
    method. This can be written as:

    switch $kind \
    $::SAME_AS_PREV {
    puts "unchanged \"$filename\""
    } $::UNCOMPRESSED {
    puts "$action \"$filename\""
    } $::ZLIB_COMPRESSED {
    puts "$action \"$filename\" (zlib compressed)"
    } default {
    puts "!!!!!!!! UNEXPECTED !!!!!!!!"
    }


    Schelte.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Harald Oehlmann@wortkarg3@yahoo.com to comp.lang.tcl on Tue Jun 24 14:06:14 2025
    From Newsgroup: comp.lang.tcl

    Am 24.06.2025 um 12:53 schrieb Schelte:
    On 24/06/2025 10:23, Mark Summerfield wrote:
    I have a switch command which is doing something I don't expect but I
    don't understand what I've done wrong. In this example the default is
    always executed but I expect the case before that to be executed.

         const UNCOMPRESSED U
         const ZLIB_COMPRESSED Z
         const SAME_AS_PREV =
         set filename somefile.txt
         set action "added"
         set kind Z
         switch $kind {
             $::SAME_AS_PREV { puts "unchanged \"$filename\"" }
             $::UNCOMPRESSED { puts "$action \"$filename\"" }
             $::ZLIB_COMPRESSED { puts "$action \"$filename\" (zlib
    compressed)" }
             default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }
         }

    What am I doing wrong?

    Switch allows for two different ways to specify the pattern/body pairs:
    As as a single argument or as individual arguments. If you want the
    patterns to be in variables (or consts) you may prefer the latter
    method. This can be written as:

    switch $kind \
      $::SAME_AS_PREV {
        puts "unchanged \"$filename\""
    } $::UNCOMPRESSED {
        puts "$action \"$filename\""
    } $::ZLIB_COMPRESSED {
        puts "$action \"$filename\" (zlib compressed)"
    } default {
        puts "!!!!!!!! UNEXPECTED !!!!!!!!"
    }


    Schelte.


    RIGHT YOU ARE !
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Robert Heller@heller@deepsoft.com to comp.lang.tcl on Tue Jun 24 12:37:28 2025
    From Newsgroup: comp.lang.tcl

    At Tue, 24 Jun 2025 08:23:45 -0000 (UTC) Mark Summerfield <m.n.summerfield@gmail.com> wrote:

    I have a switch command which is doing something I don't expect but I
    don't understand what I've done wrong. In this example the default is
    always executed but I expect the case before that to be executed.

    const UNCOMPRESSED U
    const ZLIB_COMPRESSED Z
    const SAME_AS_PREV > set filename somefile.txt
    set action "added"
    set kind Z
    switch $kind {
    $::SAME_AS_PREV { puts "unchanged \"$filename\"" }
    $::UNCOMPRESSED { puts "$action \"$filename\"" }
    $::ZLIB_COMPRESSED { puts "$action \"$filename\" (zlib
    compressed)" }
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }
    }

    What am I doing wrong?
    switch does NOT evaluate the case labels. That is, the case labels are *literally*:
    {$::SAME_AS_PREV}, {$::UNCOMPRESSED}, {$::ZLIB_COMPRESSED}


    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    heller@deepsoft.com -- Webhosting Services
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Robert Heller@heller@deepsoft.com to comp.lang.tcl on Tue Jun 24 12:37:31 2025
    From Newsgroup: comp.lang.tcl

    At Tue, 24 Jun 2025 08:46:57 -0000 (UTC) Mark Summerfield <m.n.summerfield@gmail.com> wrote:

    On Tue, 24 Jun 2025 10:37:08 +0200, Harald Oehlmann wrote:

    Am 24.06.2025 um 10:23 schrieb Mark Summerfield:
    I have a switch command which is doing something I don't expect but I
    don't understand what I've done wrong. In this example the default is
    always executed but I expect the case before that to be executed.

    const UNCOMPRESSED U const ZLIB_COMPRESSED Z const SAME_AS_PREV > >> set filename somefile.txt set action "added"
    set kind Z switch $kind {
    $::SAME_AS_PREV { puts "unchanged \"$filename\"" }
    $::UNCOMPRESSED { puts "$action \"$filename\"" }
    $::ZLIB_COMPRESSED { puts "$action \"$filename\" (zlib
    compressed)" }
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }
    }

    What am I doing wrong?

    Nothing wrong. Tcl is just different, sorry for that.

    The "{" always avoids expansion of variables and commands. If you want
    to use variables in the switch, you have to avoid the "{".

    switch -exact -- $kind [list\
    $::SAME_AS_PREV { puts "unchanged \"$filename\"" }\
    $::UNCOMPRESSED { puts "$action \"$filename\"" }
    $::ZLIB_COMPRESSED { puts "$action \"$filename\" (zlib compressed)" }\
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }\
    ]

    Nevertheless, this is no fun on the quoting level (backslashes at the
    end etc). In addition, you have to take care, when the variable
    expansion happens. This might be tricky.

    I personally would write it like that:

    switch -exact -- $kind {
    = { # SAME_AS_PREV
    puts "unchanged \"$filename\""
    }
    U { # UNCOMPRESSED
    puts "$action \"$filename\""
    }
    Z { # ZLIB_COMPRESSED
    puts "$action \"$filename\" (zlib compressed)"
    }
    default { puts "!!!!!!!! UNEXPECTED !!!!!!!!" }
    }

    Harald

    Thanks that works great.

    Bit of a disinsentive to use consts though!
    Yes. You really can't use them the way you do in C/C++. Tcl does not really have "const". It also really does not have "statements". Tcl is like LISP in many ways.


    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    heller@deepsoft.com -- Webhosting Services
    --- Synchronet 3.21a-Linux NewsLink 1.2