I'm working on a Tk project that includes the ability to edit a set of filters, much like email filters. I've come up with a scheme that uses two HList widgets to manage this.

The user interaction works nicely, but I've discovered that I've got some memory issues. Every time I select a new rule for editing, I gobble up about 110 K of ram.

Before I go into much more detail, my questions are:

Here's a gross little ASCII picture of the interface:

+--------------------------------+ | [ ] A Rule X | | [X] A Different Rule X | | + | +--------------------------------+ Name _____________________ Run if [ANY =] conditions: +--------------------------------+ |[FIELD1 =] [ > =] __________ X | |[FIELD2 =] [ < =] __________ X | |[FIELD3 =] [ is =] [ value =] X | +--------------------------------+ Legend: [FOO =] is meant to represent an Optionmenu The X and + are buttons for adding or deleting items _____ are Entry widgets The borders denote my HList widgets.

How it works

When a user selects a rule in the top HList, it is displayed in the bottom HList. The I copy the rule into my "working copy" aka my object's rule attribute. The Rule and Clause objects are basic Class::Struct based objects. Then I clean out the bottom HList by explicitly destroying the widgets in each item, and delete each entry. Then I create new entries and items and populate them with new widgets. A lot of widgets are created and destroyed in this process, but the only other option I can see is creating a pool of widgets and parceling them out or creating new ones as needed--a task I'd rather not manage.

sub EditRule { my $self = shift; my $rule = shift || 'NO_COPY'; if ( $rule ne 'NO_COPY') { $rule->copy($self->original_rule); $rule->copy($self->rule); } # This is my HList widget my $clause_list = $self->clause_list; # Here we remove all items from the HList. foreach my $path ( $clause_list->info('children') ) { print "Deleting $path\n"; foreach (0..3) { next unless $clause_list->item('exists', $path, $_); my $w = $clause_list->item('cget', $path, $_, '-widget'); # This is testing code where I try explicitly clearing out + bits the widgets I use. # It could be refined by writing an arg list to an array a +nd passing it to a generic $w->configure call. if ( ref $w eq 'Tk::Button' ) { print "\tCleaning button\n"; $w->configure( '-command'=> undef, -textvariable => undef ); } elsif ( ref $w eq 'Tk::Optionmenu' ) { print "\tCleaning Optionmenu\n"; $w->options($NULL_OPTS); $w->configure( '-command'=> undef, -textvariable => undef, ); } elsif ( ref $w eq 'Tk::Entry' ) { print "\tCleaning Entry\n"; $w->configure( -textvariable => undef, ); } $w->DESTROY; } $clause_list->delete('entry', $path); } # This gets a list of conditions or clauses for the rule # Clause is another Class::Struct based object. my $clauses = $self->rule->clauses; # Here I make a new HList item to house the NEW CLAUSE button. # methods called _W_blah_blah return a widget. $clause_list->add('new_clause'); $clause_list->itemCreate('new_clause',0, -itemtype => 'window', -widget => $self->_W_new_clause(), ); # Here I add a new entry for each clause in the rule. foreach my $i ( 0..$#{$clauses} ) { $self->DisplayClause($i); } $self->join_op->configure( -state => 'normal', ); } # END EditRule ----------------------------------------- sub DisplayClause { my $self = shift; my $i = shift; # Clause index my $clause_list = $self->clause_list; # Get my HList widget my $clause = $self->rule->clauses->[$i]; # Get the clause to displ +ay. # I know that no item exists at HList path $i. $clause_list->add($i, -before=>'new_clause'); # Create the Tix display items. # _W_foobar returns a widget. # different field values have different operator and value widgets +. $clause_list->itemCreate($i, 0, -itemtype => 'window', -widget => $self->_W_select_field($clause, $i), ); $clause_list->itemCreate($i, 1, -itemtype => 'window', -widget => $self->_W_select_op($clause), ); $clause_list->itemCreate($i, 2, -itemtype => 'window', -widget => $self->_W_select_value($clause), ); $clause_list->itemCreate($i,3, -itemtype => 'window', -widget => $self->_W_delete_clause($i), ); }

Any ideas? Comments? Rebukes for my foolishness?


TGI says moo


In reply to Tk, HLists and memory leakage by TGI

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.