may be its not reachable "perfect" refcounting, but many special cases could be covered anyways.
"sub call" in Tcl.pm could check a special cases, when widget object invokes a method, which has a code ref as argument, then in this case command within tcl will be given a special name When invoked similar thing second time, Tcl.pm will notice this, and will delete previous instance. Below are adjustments for Tcl.pm and Tk.pm. --- Tcl.pm.orig Mon Sep 12 18:40:35 2005 +++ Tcl.pm Tue Sep 27 15:57:22 2005 @@ -437,6 +437,7 @@ sub call { my $interp = shift; my @args = @_; + $current_widget = ''; # Process arguments looking for special cases for (my $argcnt=0; $argcnt<=$#args; $argcnt++) { @@ -446,14 +447,20 @@ if ($ref eq 'CODE') { # We have been passed something like \&subroutine # Create a proc in Tcl that invokes this subroutine (no args) - $args[$argcnt] = $interp->create_tcl_sub($arg); + if ($current_widget and $argcnt>=2 and !ref(my $vt=$args[$argcnt-1])) { + $args[$argcnt] = $interp->create_tcl_sub($arg,"","::perl::c$args[0]-$vt"); + } else { + $args[$argcnt] = $interp->create_tcl_sub($arg); + } $widget_refs{$current_widget}->{$args[$argcnt]}++; } elsif ($ref =~ /^Tcl::Tk::Widget\b/) { # We have been passed a widget reference. # Convert to its Tk pathname (eg, .top1.fr1.btn2) $args[$argcnt] = $arg->path; - $current_widget = $args[$argcnt] if $argcnt==0; + if ($argcnt==0) { + $current_widget = $args[$argcnt]; + } } elsif ($ref eq 'SCALAR') { # We have been passed something like \$scalar @@ -614,7 +621,14 @@ # Returns tcl script suitable for using in tcl events. sub create_tcl_sub { my ($interp,$sub,$events,$tclname) = @_; - unless ($tclname) { + if ($tclname) { + # they have name for us - this means we should take care + # to delete instances which were probably created earlier + if (exists $anon_refs{$tclname}) { + delete $anon_refs{$tclname}; + $interp->DeleteCommand($tclname); + } + } else { # stringify sub, becomes "CODE(0x######)" in ::perl namespace $tclname = "::perl::$sub"; } --- Tk.pm~ Mon Sep 12 18:40:39 2005 +++ Tk.pm Tue Sep 27 15:50:18 2005 @@ -2342,10 +2342,10 @@ _DEBUG(2, "AUTOCREATE $package$method $method (@_)\n") if DEBUG; $sub = $fast ? sub { my $w = shift; - $w->interp->invoke($w->path, $method, @_); + $w->interp->invoke($w, $method, @_); } : sub { my $w = shift; - $w->interp->call($w->path, $method, @_); + $w->interp->call($w, $method, @_); }; } _DEBUG(2, "creating ($package)$method (@_)\n") if DEBUG; These are incomplete but rather proof of concept. Following script shows that quite few procs are allocated: use Tcl::Tk qw/:perlTk/; my $mw = tkinit; my $count; my $but = $mw->Button(-text => "Hit me",-command=>sub{'qqq'}); print ref($but); $but->configure(-command => sub { $count++; }) for 0..50; print $mw->interp->infoCommands("::perl::*"), "\n"; ============ Tcl::Tk::Widget::Button::perl::c.btn02--command::perl::Eval::perl::CODE(0x1d a80dc)::perl::CODE(0x1d0ac98)::perl::w_del Questions. comments are welcome. If no-one objects, I will go this way. Best regards, Vadim.