set RegExFrom {^ >> From: }
set RegExSubj {^ >> Subj: }
set pipe [open "|tmda-pending -bs" r]
while { [gets $pipe line] >= 0 } {
switch -regexp -- $line {
{^\d+} { regsub -all {^([^\s]+).*} $line {\1} MsgID }
{^ >> From: } { regsub $RegExFrom $line {} From }
{^ >> Subj: } { regsub $RegExSubj $line {} Subj }
{^<} {
set MsgArray($MsgID) [list $From $Subj]
unset MsgID From Subj
}
default continue
}
}
close $pipe
but only because I'm not using a variable in the switch pattern. The
variables work in the body, but not in the pattern. Can anyone help me
understand why?
--
Unabashedly littering the information superhighway with detritus like
this for over 15 years now.
Why? That's just the way it is designed to work.
You can use the alternate form of switch, which is
switch <options> pattern body ?pattern body?
For example:
switch -regexp -- $line \
$pattern1 {
....
} \
$pattern2 {
....
}
Note that you have to use lots of continuation lines for this method,
but it does allow substitutions on the patterns. You can mostly avoid
that if you put the patterns on the same line as the end of the previous
body:
switch -regexp -- $line \
$pattern1 {
....
} $pattern2 {
....
} $pattern3 {
....
}
}
>
> I have a snippet here that works:
>
> set RegExFrom {^ >> From: }
> set RegExSubj {^ >> Subj: }
> set pipe [open "|tmda-pending -bs" r]
> while { [gets $pipe line] >= 0 } {
> switch -regexp -- $line {
> {^\d+} { regsub -all {^([^\s]+).*} $line {\1} MsgID }
> {^ >> From: } { regsub $RegExFrom $line {} From }
> {^ >> Subj: } { regsub $RegExSubj $line {} Subj }
> {^<} {
> set MsgArray($MsgID) [list $From $Subj]
> unset MsgID From Subj
> }
> default continue
> }
> }
> close $pipe
>
> but only because I'm not using a variable in the switch pattern. The
> variables work in the body, but not in the pattern. Can anyone help me
> understand why?
How *exactly* are you quoting things????
I would expect this to work:
set RegExFrom {^ >> From: }
set RegExSubj {^ >> Subj: }
set pipe [open "|tmda-pending -bs" r]
while { [gets $pipe line] >= 0 } {
switch -regexp -- $line {
{^\d+} { regsub -all {^([^\s]+).*} $line {\1} MsgID }
"$RegExFrom" { regsub $RegExFrom $line {} From }
"$RegExSubj" { regsub $RegExSubj $line {} Subj }
{^<} {
set MsgArray($MsgID) [list $From $Subj]
unset MsgID From Subj
}
default continue
}
}
close $pipe
But not this:
set RegExFrom {^ >> From: }
set RegExSubj {^ >> Subj: }
set pipe [open "|tmda-pending -bs" r]
while { [gets $pipe line] >= 0 } {
switch -regexp -- $line {
{^\d+} { regsub -all {^([^\s]+).*} $line {\1} MsgID }
{$RegExFrom} { regsub $RegExFrom $line {} From }
{$RegExSubj} { regsub $RegExSubj $line {} Subj }
{^<} {
set MsgArray($MsgID) [list $From $Subj]
unset MsgID From Subj
}
default continue
}
}
close $pipe
>
--
Robert Heller -- 978-544-6933
Deepwoods Software -- Linux Installation and Administration
http://www.deepsoft.com/ -- Web Hosting, with CGI and Database
hel...@deepsoft.com -- Contract Programming: C/C++, Tcl/Tk
Expect to be disappointed. That's not how the switch command works.
Note that this case of [switch] syntax is *precisely* intended for use
with variables containing patterns (and command-substitutions returning
patterns, and other more complex stuff). The other form is only really
for the (OK, massively common) case of static patterns.
Donal.
>> but only because I'm not using a variable in the switch pattern. The
>> variables work in the body, but not in the pattern. Can anyone help me
>> understand why?
>
> How *exactly* are you quoting things????
>
>
> I would expect this to work:
>
> set RegExFrom {^ >> From: }
> set RegExSubj {^ >> Subj: }
> set pipe [open "|tmda-pending -bs" r]
> while { [gets $pipe line] >= 0 } {
> switch -regexp -- $line {
> {^\d+} { regsub -all {^([^\s]+).*} $line {\1} MsgID }
> "$RegExFrom" { regsub $RegExFrom $line {} From }
> "$RegExSubj" { regsub $RegExSubj $line {} Subj }
> {^<} {
> set MsgArray($MsgID) [list $From $Subj]
> unset MsgID From Subj
> }
> default continue
> }
> }
> close $pipe
>
and your expectations would not be met.
look at the forth argument to your switch statement. it
is quoted with {} which means that *no* substituion will occur
just becaus there are quotes inside of it don;t make a difference
to parser - that outer word is quoted with {} so the whole thing is
passed as is to the switch statement - which doesn't do any extra
substitutions on the pieces.
The right answer is to use the form of switch that takes the pattern
and action as sepearate arguments, not all lumped together, then the
parser will expand them as needed (depending on quoting of course)
Bruce
Now I'm confused. Bryan, what do you expect of
set value abcdefgh...wxyz
switch -regexp -- $value {
"ab.*xyz" {
puts Success.
}
default {
puts Failure.
}
}
? Maybe I've lost track of the antecedent for the
"That" in your last sentence.
Success. The question was about variables in the patterns; your example
doesn't include variables in the patterns.
> In article <fc75h.6712$yl4....@newssvr12.news.prodigy.com>,
> Bryan Oakley <oak...@bardo.clearlight.com> wrote:
> >Robert Heller wrote:
> >> I would expect this to work:
> >> ...
> >> switch -regexp -- $line {
> >> {^\d+} { regsub -all {^([^\s]+).*} $line {\1} MsgID }
> >> "$RegExFrom" { regsub $RegExFrom $line {} From }
> >
> >Expect to be disappointed. That's not how the switch command works.
>
> Now I'm confused. Bryan, what do you expect of
>
> set value abcdefgh...wxyz
>
> switch -regexp -- $value {
> "ab.*xyz" {
> puts Success.
> }
> default {
> puts Failure.
> }
> }
That would work (everything is literal inside switch). But
set patt "ab.*xyz"
set value abcdefgh...wxyz
switch -regexp -- $value {
"$patt" {
puts Success.
}
default {
puts Failure.
}
}
would not as outer braces (the ones starting after $value) would prevent
$patt from being substituted (thus switch would compare _value_ of value
to _literal_ "$patt"). That is "That".
> ? Maybe I've lost track of the antecedent for the "That" in your last
> sentence.
--
-Kaitzschu
s="TCL ";while true;do echo -en "\r$s";s=${s:1:${#s}}${s:0:1};sleep .1;done
The confusion might come from the fact that you _can_ use variables
inside the actions, but not in the patterns, if the {} form is used.
Eg.
switch -- $value {
foo {
# can use variables here, but not in the pattern line directly above
puts "value is $value"
}
}
If you need substitution in the patterns, use the form of switch with
separate arguments for patterns and actions
switch -- $value \
$patt1 {
} \
$patt2 {
}
R'
But that is clearly stated in the man pages. In this case the interpreter
does NOT substitute in either the pattern or bodies, they are passed literally
to the switch command which does t he following:
The switch command matches its string argument against each of the pattern arguments in order. As
soon as it finds a pattern that matches string it evaluates the following body argument by passing
it recursively to the Tcl interpreter and returns the result of that evaluation.
(quoted from http://www.tcl.tk/man/tcl8.4/TclCmd/switch.htm)
so the is no magic goping on - initially NO substitution occurs, then is a pattern
is matched the body associated is passed again to the interpreter - this is when
the variables are/commands are substituted.
Bruce
More to that (cited from same source):
Since the pattern arguments are in braces in the second form, no
command or variable substitutions are performed on them; this makes
the behavior of the second form different than the first form in some
cases.
| so the is no magic goping on - initially NO substitution occurs,
| then is a pattern is matched the body associated is passed again to
| the interpreter - this is when the variables are/commands are
| substituted.
Yup. The prolonged existence of this whole thread raises the
question: how to make people (like me) who think they know TFM
RTFMAAAน ;-)
R'
---
น RTFM _A_gain _A_nd _A_gain...