Deutsch   English   Français   Italiano  
<103dpb8$1s2ei$4@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: Harald Oehlmann <wortkarg3@yahoo.com>
Newsgroups: comp.lang.tcl
Subject: Re: misunderstaning of switch command
Date: Tue, 24 Jun 2025 10:58:17 +0200
Organization: A noiseless patient Spider
Lines: 81
Message-ID: <103dpb8$1s2ei$4@dont-email.me>
References: <103dnah$1tams$1@dont-email.me> <103do3k$1s2ei$3@dont-email.me>
 <103dom1$1tams$2@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 24 Jun 2025 10:58:17 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="c298b2c3f9e49450bb0b13b061c6e981";
	logging-data="1968594"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX18DE1Z8ayxFkGsVEPk0MTz5"
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:ThlKCgl0uvPPrn+ZYvnQ0Jeze5Y=
In-Reply-To: <103dom1$1tams$2@dont-email.me>
Content-Language: en-GB

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