in reply to Clearing anonymous Tk widgets

To properly closure you should write
my $goner = $_; ... sub { delete $runtime{$goner} }

Replies are listed 'Best First'.
Re^2: Clearing anonymous Tk widgets
by murrayn (Sexton) on Aug 31, 2012 at 10:03 UTC
    I did consider that but I don't know the name of $goner in advance. There might be one line in the input file or there might be 50. So what I'm trying to achieve is a loop scanning all lines in the input file (they are loaded into a hash by XML::Simple) then building an entry in a Tk GUI window for each line. There are three columns: keyword (as a read only Label), value (r/w as an Entry) and a delete button. The delete button should do two things: remove the entry from the hash with key=keyword and remove (destroy?) the row in the GUI window.

      Play with this

      #!/usr/bin/perl -- use strict; use warnings; use Tk; use Tk::WidgetDump; use Tk::ObjScanner; my %ons; my $mw = tkinit(); for (1 .. 3) { my $goner = $_; $ons{$_} = $mw->Button( -text => "B $_", -command => sub { delete($ons{$goner})->destroy; ## this works, proper closu +re #~ delete($ons{$_})->destroy; ## this doesnt, $_ is alias } )->pack; } $mw->WidgetDump; ## before scan_object Tk::ObjScanner::scan_object( { mw => $mw, ons => \%ons } ); ## after W +idgetDump MainLoop();
        That looks promising. I'll have a play over the next few days (it's Father's Day in Aus tomorrow - there'd be trouble if I was messing with Perl code then!). I was starting to think I'd need an array of Tk Frames and go destroying them but this looks more elegant. Thanks. I'll let you know how it goes.

      I did consider that but I don't know the name of $goner in advance.

      Yes you do, its $_, its the keys of %runtime -- if thats not the case, you'll have to restate your question

        Unless I've done something silly (highly plausible explanation!), I'm not seeing evidence to support that theory. $_ is the value of the key when I build the line in the GUI window and it displays exactly as I'd expect it to and when I put a button on the line saying delete $runtime{$_} it works the first time then objects the second time (makes sense too - the delete worked, so there's nothing there now). So now I want to remove the line from the GUI and I don't have a Tk widget name to destroy.