Home > Archive > Tcl > August 2007 > need repeat command
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
need repeat command
|
|
| Michael Reichenbach 2007-08-26, 7:18 pm |
| Well... It works, but...
proc repeat { times what } {
for { set x 0 } { $x < $times } { incr x } {
set ::temp $what
uplevel 1 { eval $::temp }
unset ::temp
}
}
#repeat 2 { puts test }
#--> test test
It`s kinda ugly, isn`t it. I think you see what command I want to have.
Can you help me out and write this a bit better?
| |
| Jonathan Bromley 2007-08-26, 7:18 pm |
| On Mon, 27 Aug 2007 00:17:13 +0200, Michael Reichenbach
<Reichenbach@discardmail.com> wrote:
>Well... It works, but...
>
>proc repeat { times what } {
> for { set x 0 } { $x < $times } { incr x } {
> set ::temp $what
> uplevel 1 { eval $::temp }
> unset ::temp
> }
>}
I don't quite see why you're messing around with a special
global to hold the script; and [uplevel] does an [eval]
for you anyway; so the same thing can be done quite a bit
more succinctly without any change of meaning:
proc repeat {n script} {
while {$n > 0} {
uplevel 1 $script
incr n -1
}
}
Of course, it needs quite a lot of bullet-proofing;
in particular, the "n" argument needs to be checked
using [string is integer] or somesuch, and you probably
need to decide carefully what to do if n is negative.
I suppose you could code the loop thus:
while {[incr n -1] >= 0} {uplevel 1 $script}
so allowing [incr] to catch non-integer $n for you.
--
Jonathan Bromley, Consultant
DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services
Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com
The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
| |
| suchenwi 2007-08-27, 4:38 am |
| In fact Tcl, has a built-in repeat command:
$ tclsh
% time {puts hello} 5
hello
hello
hello
hello
hello
3200 microseconds per iteration
%
You're free to ignore the result of [time], and can still use the
counted repetition very efficiently :^)
[break] and [continue] are not available here, however.
| |
| slebetman@yahoo.com 2007-08-29, 4:33 am |
| On Aug 27, 6:45 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
> On Mon, 27 Aug 2007 00:17:13 +0200, Michael Reichenbach
>
> <Reichenb...@discardmail.com> wrote:
>
>
> I don't quite see why you're messing around with a special
> global to hold the script; and [uplevel] does an [eval]
> for you anyway; so the same thing can be done quite a bit
> more succinctly without any change of meaning:
>
> proc repeat {n script} {
> while {$n > 0} {
> uplevel 1 $script
> incr n -1
> }
> }
>
Apart form error checking $n, proper handling of break, continue and
return is also a bit tricky but not too hard. I usually do something
like:
proc repeat {n script} {
while {$n > 0} {
set code [catch {uplevel 1 $script} result]
if {$code} {
return -code $code $result
}
incr n -1
}
}
| |
| Andreas Leitgeb 2007-08-29, 8:11 am |
| If the loop-variable isn't needed nor "break" nor "continue" then
time {puts 42} 42
is the simplest method to write 42 times the text "42".
if you call it on an interactive tcl shell prompt, it will also tell
you the average time consumed per iteration, but inside a script you
don't need to worry about that. (unless you *want* the info: then you
just use the result of the time command: set tm [time ...])
|
|
|
|
|