Ok, i think i know what is going wrong
At https://github.com/gisle/tcl.pm/blob/master/Tcl.pm line 553 you find
Notice that line 551-552 notes plan deleting that entry, hence Tcl command during Tcl::Code::DESTROY TODO - this +1000 is wrong... should$interp->invoke('after',$args[1]+1000, "perl::Eval {Tcl::_code_dispose +('$interp;$id')}");
To backtrack a little, at https://st.aticpan.org/source/SREZIC/Tk-804.034/demos/timer i found a simple timer in Tk. after some heavy handed munging to Tkx i got
Running that, then pressing start caused the "invalid command name "::perl::CODE" error too. Ahah, something else fails too!#!/usr/bin/env perl # # to Tkx from https://st.aticpan.org/source/SREZIC/Tk-804.034/demos/ti +mer # # This script generates a counter with start and stop buttons. # # original Tcl/Tk -> Perl translation by Stephen O. Lidie. lusol@Lehi +gh.EDU 96/01/25 require 5.002; use Tkx; use strict; use warnings; my $mw=Tkx::widget->new("."); # %tinfo: the Timer Information hash. # # Key Contents # # w Reference to MainWindow. # s Accumulated seconds. # h Accumulated hundredths of a second. # p 1 IIF paused. # t Value of $counter -textvariable. my(%tinfo) = ('w' => $mw, 's' => 0, 'h' => 0, 'p' => 1, 't' => '0.00 +'); my $w_tfrm = $mw->new_ttk__frame(); my $counter= $w_tfrm->new_label(-textvariable =>\$tinfo{'t'} ,-justify =>'left' ,-anchor =>'nw' ,-font =>'TkFixedFont' ); my $start=$w_tfrm->new_ttk__button(-text=> 'Start', -command=>sub {i +f($tinfo{'p'}) {$tinfo{'p'} = 0; tick()}} ); my $stop =$w_tfrm->new_ttk__button(-text=> 'Stop' , -command=>sub {$ +tinfo{'p'} = 1;} ); $counter->g_grid(-column=>0,-row => 0, -sticky=>'ew'); $start ->g_grid(-column=>0,-row => 1, -sticky=>'ew'); $stop ->g_grid(-column=>1,-row => 1, -sticky=>'ew'); $w_tfrm->g_pack(qw '-fill x -expand false -anchor nw'); Tkx::MainLoop; exit; sub tick { # Update the counter every 50 milliseconds, or 5 hundredths of a s +econd. return if $tinfo{'p'}; $tinfo{'h'} += 5; if ($tinfo{'h'} >= 100) { $tinfo{'h'} = 0; $tinfo{'s'}++; } $tinfo{'t'} = sprintf("%d.%02d", $tinfo{'s'}, $tinfo{'h'}); my $send_id=Tkx::after( 50 , \&tick); } # end tick
So i modified my code to have a constant rather than random delay time. And lo and behold the failures became regular, The failure occurs 1 second after the first call to Tkx::After with the scalar coderef. one second became interesting
so i modifed my test code and added
then added after_dump(); to the end of accept_out_cclose_after. Thats when i noticed lines likesub after_dump{ my $info0=Tkx::after_info(); if (ref($info0) ne 'Tcl::List') { print "not tkx list\n"; $info0=[Tkx::SplitList($info0)]; } for my $send_id (@$info0) { my $info1=Tkx::after_info($send_id); print 'after:'.sprintf('%-15s',$send_id).' script-'.$info1->[0].' +type-'.$info1->[1]."\n"; } }
Thats what gave me to clue(_code_dispose) to find out where the argument processing was for Tcl calls from perl, and i found that 1 second after the my Tkx::after call terminates _code_dispose was destroying the majic that allowed it to call that perl subroutine coderef, even though that coderef was a "static scalar".after:after#3 script-perl::Eval {Tcl::_code_dispose('Tcl=SCALA +R(0x871eb00);after#2')} type-timer after:after#2 script-::perl::CODE(0x89f20c8) type-timer
I kinda have a clue how to fix this, but ive been digging around so much me brain is all jumbled right now.
as for why it worked in win but not ubuntu my windows has $Tcl::VERSION = '1.02'; which was installed when i installed 5.20, but ubuntu 14.04/16.04/18.04 has $Tcl::VERSION = '1.05'; installed just a few days ago. I suspected the version were different, but still wanted to understand why it failed.
In reply to Re: Tkx after coderef problem
by huck
in thread Tkx after coderef problem
by huck
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |