[Melbourne-pm] TK repeats, scoping and keeping track of objects

Mathew Robertson mathew.robertson at netratings.com.au
Mon Jan 12 16:36:03 PST 2009



Leigh Sharpe wrote:
> Hi All,
>  I'm working on a TK app, and I'm struggling with a few things.
> I have a function which looks a bit like this:
>  
> sub new_object
> {
>  my $object=My::Class->new();           # Create a new object to monitor
>  my $tl=$mw->Toplevel;                      # Create a top-level window.
>  $tl->title($object->{'name'});                # Set the title of the 
> new window.
>  $tl->Label(-text=>"Name:")->grid(-row=>0, -column=>0); # Add Labels 
> to window.
>  $tl->Label(-textvariable=>\$object->{'name'})->grid(-row=>0, -column=>1);
>  $tl->Label(-text=>"IP Address")->grid(-row=>1, -column=>0);
>  $tl->Label(-textvariable=>\$object->{'ip'})->grid(-row=>1, -column=>1);
>  $tl->Label(-text=>"Uptime:")->grid(-row=>2, -column=>0);
>  $tl->Label(-textvariable=>\$object->{'uptime'})->grid(-row=>2, 
> -column=>1);
>  $tl->Button(-text=>"Exit", 
> -command=>sub{$tl->destroy()})->grid(-row=>20, -column=>0); # Create 
> an exit button.
>  $tl->repeat(5000, sub{$object->update_status()}); # Update the status 
> every 5 seconds.
> }
>  
> Now this works as it is, but I just know it won't scale well. I would 
> rather have a single class method I could call which would run 
> update_status() on all objects of it's class, and call it from the 
> main window ($mw in this case). So my first question is, how can a 
> class access all instances of itself? I considered creating an array 
> in which I could store a reference to all objects, but that just seems 
> wrong, 'cause it will prevent objects from going out of scope when all 
> other references to them are deleted.
I'm assuming that this new_object function is in the package 
"Package::Blah".  If not, then it probably should be.

So:

  package Package::Blah;
  our $SOMEVARIABLE;

then in your other code:

  $Package::Blah::SOMEVARIABLE = "fred";

ie: just refer to the full package name.
>  
> The second question is in relation to keeping $object in scope. If I 
> remove the last line of the above function, $object goes out of scope 
> as soon as the function completes. Having a label with 
> -textvariable=>\$object{'anything'} isn't sufficient to keep $object 
> in scope.
Then you need to keep a package reference to it, eg in Package::Blah:

our @SOMELIST;
push @SOMELIST, $object;

> So, if I was to create a class method as required, there would be no 
> objects to call update_status() on.
map { $_->update() } @Package::Blah::SOMELIST;
> However, with the function as it is above, even destroying $tl (when 
> the user clicks on the 'Exit' button) doesn't call DESTROY on $object. 
> There must be some reference to the object somewhere, created by 
> $tl->repeat(), which isn't going out of scope when $tl is destroy()ed.
Are you sure its not being destroyed?

cheers,
Mathew
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/melbourne-pm/attachments/20090113/0bd5bfa0/attachment.html>


More information about the Melbourne-pm mailing list