For Programmers: Free Programming Magazines  


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 ...])
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com