Edit this page: http://wiki.tcl.tk/edit/12777@
TABLE OF CONTENTS (Advanced Tcl):
List Examples: The "Lrange" Command
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.)