Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem trouble shooting using puts

25 views
Skip to first unread message

Richard Owlett

unread,
May 14, 2011, 4:21:55 PM5/14/11
to
I wrote a routine that used a "foreach". It didn't work as
expected so I sprinkled with "puts". I didn't get the expected
result.

A trivialized example is


set test_vector "1 2 4 2 5 9 2 4 6"
set element_index 1;
foreach tst_value $test_vector {
;# first part of a diagnostic print
puts -nonewline "working with element # $element_index "
after [expr {int($tst_value * 500)}]
;# rest of the diagnostic print
puts $tst_value
incr element_index
}

My problem is that nothing is displayed until ALL elements have
been processed. In my case the input list could be very long and
the body {simulated here by the "after" statement) was
intrinsically long and would get stuck for one perverse value in
the input list. [solved with appropriate bounds checking ;]

I expected to get diagnostic output for each element of the input
list. Is there any way to get "immediate" feedback?

TIA

Jeff Godfrey

unread,
May 14, 2011, 4:48:01 PM5/14/11
to
On 5/14/2011 3:21 PM, Richard Owlett wrote:
> I expected to get diagnostic output for each element of the input list.
> Is there any way to get "immediate" feedback?

Try adding:

flush stdout

after the puts command(s).

Jeff

Robert Heller

unread,
May 14, 2011, 6:24:26 PM5/14/11
to

What operating system? What is stdout bound to? A UNIX tty device? A
pipeline? The tk_console under MS-Windows?

If it is to a a UNIX tty device (eg it a run from a tclsh script from an
xterm), the output should be as you expect. If you are piping it to a
log file which you are reading with 'tail -f logfile' in another
process, things will depend on the file I/O buffering. If to the
tk_console under MS-Windows, it will wait until the event loop is
reentered.

Commands to consider using: flush (to flush the output buffer), update
(to reenter the event loop).

>
> TIA
>

--
Robert Heller -- 978-544-6933 / hel...@deepsoft.com
Deepwoods Software -- http://www.deepsoft.com/
() ascii ribbon campaign -- against html e-mail
/\ www.asciiribbon.org -- against proprietary attachments



Uwe Klein

unread,
May 14, 2011, 6:35:14 PM5/14/11
to
Richard Owlett wrote:
> I wrote a routine that used a "foreach". It didn't work as expected so I
> sprinkled with "puts". I didn't get the expected result.
>
> A trivialized example is
>
>
> set test_vector "1 2 4 2 5 9 2 4 6"
> set element_index 1;
> foreach tst_value $test_vector {
> ;# first part of a diagnostic print
> puts -nonewline "working with element # $element_index "
# insert:
flush stdout
# or insert in the initialisation:
fconfigure stdout -buffering none

> after [expr {int($tst_value * 500)}]
> ;# rest of the diagnostic print
> puts $tst_value
> incr element_index
> }
>
> My problem is that nothing is displayed until ALL elements have been
> processed. In my case the input list could be very long and the body
> {simulated here by the "after" statement) was intrinsically long and
> would get stuck for one perverse value in the input list. [solved with
> appropriate bounds checking ;]
>
> I expected to get diagnostic output for each element of the input list.
> Is there any way to get "immediate" feedback?

you would get output in blocksizes of the line buffering discipline
probably ~1 .. 4 kbytes ;-)
the default for stdout on a tty is linebuffering.
your use of -nonewline sabotages the continuous flow of output.
>
> TIA

G!
uwe

Richard Owlett

unread,
May 14, 2011, 7:27:12 PM5/14/11
to

Thanks all
Environment: wish85.exe under WinXP Pro
The solution was using "update idletasks" after each "puts".
[presence of "-nonewline" turned out to not be an issue]
The use of "flush stdout" had no effect [had replaced "puts"
explicitly with "puts stdout"].

Now I can try dealing with my original goal ;/


Robert Heller

unread,
May 14, 2011, 9:14:29 PM5/14/11
to

Ah, it is because of the *event driven* graphics update.

Unless you code is GUI based, you might do better to fire up a command
window and using tclsh85.exe instead.

Richard Owlett

unread,
May 15, 2011, 7:25:55 AM5/15/11
to

Ahhh, the subtle differences between wish an tclsh shells.

President

unread,
May 19, 2011, 1:30:23 PM5/19/11
to

I discovered this last year and posted an article on my blog about it.
http://www.aspenlogic.com/blahblahblog.php?s=update-idletasks-more-tcl-secret-sauce

The key is to understand that the event loop was moved from TK to TCL
(around Tcl 7.5/Tk 4.1 release.) The update idletasks command forces
an entry into the event loop. This is an important trick to understand
for all I/O processing code. The update (without idletasks) command is
also important when watching variables in TK code.

Richard Owlett

unread,
May 19, 2011, 7:57:55 PM5/19/11
to

BUT BUT BUT BUT ;/
Thought I was in 'procedural universe of discourse'


Andreas Leitgeb

unread,
May 20, 2011, 1:18:20 PM5/20/11
to
Richard Owlett <row...@pcnetinc.com> wrote:
>>> Environment: wish85.exe under WinXP Pro
>>> The solution was using "update idletasks" after each "puts".
>>> [presence of "-nonewline" turned out to not be an issue]
>>> The use of "flush stdout" had no effect [had replaced "puts"
>>> explicitly with "puts stdout"].

The problem is, that the window you interact with is really a
window of the same process that also runs your code (the loop).

You wouldn't have to resort to "update idletasks", if your
tclsh was running in the console/terminal (so the process
doing the gui would be a different one than the one running
your code.

Output to a GUI window typically needs the event-loop.
Output to channels typically doesn't need it, unless the command
doing it (puts) is replaced by one actually doing GUI window output.

0 new messages