Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

"after" command doesnot work in tclsh

Status
Not open for further replies.

charmdream

Programmer
Oct 26, 2001
25
0
0
US
After" works fine in wish, but doesn't work in tclsh.
Anybody had this experience? How to solve it?

Thanks
 
After works fine for me in tclsh.
What version and OS are you using (I use Tcl 8.4.5 on Windows)?

Bob Rashkin
rrashkin@csc.com
 
I tried tclsh8.0, tclsh8.3 and tclsh8.4 on solaris. All have the same problem.
Did you try "after <ms> {script}"? If only "after <ms>", it works.
 

The following is the manual for "after":

The after ms and after idle forms of the command assume that the application is event driven: the delayed commands will not be executed unless the application enters the event loop. In applications that are not normally event-driven, such as tclsh, the event loop can be entered with the vwait and update commands.

I have tried to use "vwait", but vwait will be blocked there. I may lose some info there. Does anybody have other solution?

Thanks
 
After works fine.
I'm not sure what you are trying to do with it however.
Code:
set time 10000
proc callback { {n "0"}} {
global time
         incr time $time
         after $time; return [incr n] 
}
set i 0
while {1} {
          set i [callback $i]
          puts "Time is now $time at $i"
          set time [expr $time / 2]
          puts -nonewline stdout "Want to quit(y/n): "
          flush stdout ; set ans [gets stdin]
          if {"$ans" == "y"} {break}
          puts "time = $time"
}

If you are just calling after in hopes of it
running in perpetuity without recursion or
a control loop like that above you are not
explaining something to us. Use vwait if this
is the case. It works as expected.
 
Hi, marsd

Please try to execute
after 1000 {puts hello}
under tclsh and wish respectively.
You will see the difference.
 
After behaves as expected in both cases.
A one second pause followed by the output
of puts.
What are you trying to tell us? There is
no mystery here IMO. The only thing missing
is a concise description of your issue and
a sample of the problematic code.
 
which version of tclsh are you using?
I tried tclsh8.0, tclsh8.3 and tclsh8.4 on solaris.
The command
after 1000 {puts hello}
didn't give the output after 1 second.
But if using wish, it works.
I have known it's because tclsh doesn't support event-driven.

I don't know how you could get the output from tclsh.
 
I'm not on solaris.
It works without fail on linux and windows xp.
Using tcl 8.4.6 and I've been using Tcl and after
with the same predictable output for many years
as you can probably see from my posts on this site. ;)
I do remember one episode with after in 8.2 or 8.3
that was problematic and I believe there was a bugfix.
You should try comp.lang.tcl with your issue.
The solaris maintainers and devs there could give
you a definitive answer to your question. In the
meantime how about exec'ing sleep or writing a simple
C program to emulate after. Wouldn't be too difficult.

Try this also:
Code:
after $time; puts $msg
 
I also tried tclsh8.4 on linux. It failed too. Though not trying on windows(may try later), I believe it should behave the same. I felt very surprise how you could succeed!
Are you sure you used tclsh (not wish)?
And use the ONE command: after 1000 {puts hello}
Actually, I have found some information on this:
Since tclsh is not event-driven, the pending events(expired timer) will not be handled until "vwait" or "update" command is executed.
After running "after 1000 {puts hello}" in tclsh, you can see the timer info through "after info". It's always there!
But "after 1000" is different with "after 1000 {puts hello}". "after 1000" can just wait 1 second then return when running in tclsh.

Now I already got the solution for this problem. In the system main loop, calling Tcl_DoOneEvent() to check the pending timer event.

Thanks for the input.
 
I'm sorry but the problem you describe does not exist
for me and many others. I suspect you are doing something wrong, please don't be offended. Little errors can make
big differences.

Here is some empirical evidence.
tclsh
% time {after 1000; puts "Hi"}
Hi
1000984 microseconds per iteration
% time {puts "HI"}
HI
59 microseconds per iteration
 
Hi marsd,

I read your post and knew the difference between what you tried and what I tried.

Please try the command:
after 1000 {puts Hi}

NOTE: NO SEMICOLON! i.e. NOT "after 1000; puts Hi".
Because it is different command. This command will block the execution, which is not what I want.

I believe you will see the difference.

Thanks for the post.

 
As it turns out, "after" is really a Tk command (see Welch's book). If you do your test in a Wish shell, you'll find it works. Also, you don't need the braces ({}).

Bob Rashkin
rrashkin@csc.com
 
I just realized: that's what you started with. Oh well.

Bob Rashkin
rrashkin@csc.com
 
If you want a non-blocking execution then you are
correct.
If you say that "after does not work", you are wrong.
But now I see what you are getting at.

If I really want to have non-blocking execution in
tclsh using 'after' I'd have to fork/thread another
instance/thread and continue in the parent I guess.
That may not be an option but is the logical thing to
do.

Try this if you are on a unix that has the expect
extension or tclX extension available.
Code:
if {[catch {package require Expect}]} {
    if {[catch {package require Tclx}]} {
        error "Couldn't load either package for fork()"
    }
}    
set time 12000
set wrote 0
proc calltime {} {
global time wrote
      puts "\nTime UP!!!!\n"
      after $time; calltime
}

if {[set id [fork]] == 0} {
    calltime
   } else {
   while {1} {
             puts -nonewline stdout "Quit this process(y/n): "
             flush stdout
             set ans [gets stdin]
             if {"$ans" == "y"} {exit}
   }
 }
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top