NAVIGATION
TABLE OF CONTENTS (Advanced Tcl):
SEE ALSO:
Lists - The Lrange Command - Complex Data Structures Using Lists
2003/01/20
Is there a real way to do the following?
proc lranges {list args} { set start 0 set newlist {} foreach size $args { set end [expr {$start + $size - 1}] lappend newlist [lrange $list $start $end] incr start $size } if {$start <= [llength $list]} { lappend newlist [lrange $list $start end] } return $newlist } % lranges "1 2 3 4 5 6 7" 2 3 5 {1 2} {3 4 5} {6 7}
I was getting tired of parsing things with continual lranges and I kept wishing I could foreach over a however many elements I wanted to grab for the next variable instead of just one.
Not sure this has a good default behavior, and I should probably error handle non integer args.
BR 2004-01-21 - Can you give an real example of what you want to do? Are you looking for something like:
foreach {label value} {firstname "Benny" lastname "Riefenstahl"} { # Do something with $label and $value }
sheila 2004-01-21 - I'd like to be able to do this:
foreach {opcode control data1 data2} {01 02 89 24 35 87 52 45 38 48} {break}
opcode will be 01, control 02, data1 {89 24 35 87 52}, and data2 {45 38 48}
assuming that I know the byte count of each field. iow:
set message {01 02 89 24 35 87 52 45 38 48} foreach {opcode control data1 data2} [lranges $message 1 1 5] {break}
instead of
set opcode [lrange $message 0 0] set control [lrange $message 1 1] set data1 [lrange $message 2 6] set data2 [lrange $message 7 end]
There are more complicated uses (like with a byte count field, and then foreaching based on that), but is this example sufficient?
BR 2004-01-22 - To answer the original question, no I don't think there is a built-in solution for this. But if you are ok with the concept, your proc is o.k., isn't it? I personally would probably prefer to write it out as you do above, unless I have lots of repeating code in a specific module.
Notes:
sheila 2004/01/22 - Thanks. I wanted to make sure I wasn't overlooking some tcl function. The reason I want the proc is that I don't like all of the hard coded numbers making my parsers unreadable. I make data structures for the commands, and then I have retrieval proc to return whatever value of the command I specify in the structure, i.e. byte length, length of a field, etc. That way I can have self-documenting code. Also, when I do pass in a value in a message that represents a byte length, and the message I'm parsing is variable length based on another value that is the number of foobar in the message. Then using the lranges command makes it a lot easier to read rather than many lrange calls for however many fields are in the fields that I'm parsing. (once I asked in the newsgroup whether there was a package anyone had written to already do this, but there wasn't.)
I suppose I make the trade off in efficiencey for readability, but I don't think it will slow down the parsing enough to be a problem.
Is there a better way to do this? (am I making this question too long for this page? apologies. I could move it somewhere else.)
Tcl String Command Syntax/Usage: Concat - Subst - Args
14/Aug/2003
I am trying to define a data structure recursively and can't get it to work.
Any suggestions?
The idea is from: http://users.pandora.be/koen.vandamme1/papers/tcl_fileformats/tcl_fileformats.html
I would expect "A=atts" I would expect "B={atta bttb} {cttc dttd}" Then I would expect "A=pins" I would expect "B={pin4 four} {pin5 five}"
I do not get that. I have also tried numerous other things like concat, subst, etc... to no avail.
proc mycommand { args } { foreach { a b } [concat $args] { puts "A=$a" puts "B=$b" } } mycommand { atts { { atta bttb } { cttc dttd } } pins { { pin4 four } { pin5 five } } }
tje Aug 20 2003 - Try this:
proc mycommand {in} {foreach {a b} $in { puts "A=$a" ; puts "b=$b" } }
Remember that args is a special argument that wraps multiple arguments into one.