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

Jacinta Richardson jarich at perltraining.com.au
Mon Jan 12 18:48:02 PST 2009


I've embedded my comments in your code (after a little reformatting).  For what
it's worth, the common place to see comments regarding a line of code is above
that line, not below.  I realise you've generally put them at the end, but - at
least to me - this only works for short lines.  Otherwise putting them at the
end hides them off the side of the window without wrapping or hides them amongst
code when the line wraps (and makes perltidy sad too).  I've moved comments on
long lines up to above the line they refer to.

It's a comment on style; of course you should be consistent with whatever style
guidelines your workplace has specified.  ;)

> in My_Package.pm:
> -----
> #!c:\perl\bin\perl

#! lines are not required for modules (and are probably best omitted).

> use strict;
> use warnings;
>
> package My::Class;

Ideally, your package line should be the first line in your file, and all use
statements should come after it.  For strict and warnings this isn't a problem,
but if you were to "use base qw(Exporter);" (for example) above your package
line, then that would almost certainly not have the desired effect.

> sub new {
>     my $class = shift;
>
>     # Get the class we have been called with.
>     my $self = {};
>
>     # Create anonymous hash to bless.
>     $self->{'name'}   = "fred";
>     $self->{'uptime'} = 1;
>
>     # And some other initialisation here.
>     bless $self, $class;
>
>     # Bless the object into the correct namespace.
>     return $self;
>
>     # Return the newly-blessed object.
> }
>
> sub update_status {
>     my $self = shift;
>     $self->{'uptime'}++;
>     return 1;
> }
>
> sub DESTROY {
>     my ($self) = @_;
>     print $self->{name}, " is being destroyed\n";
> }
>
> 1;
>

> -----
> Nothing difficult in there. Now, in my application:
> ----

A shebang line here wouldn't go astray.

> use strict;
> use warnings;
> use Net::SNMP;
> use Tk;
> use My_Package;
>
> # Create the main window object.
> my $mw = MainWindow->new( -title => "Leigh's Test App" )
>   or die "Can't create main window: $!\n";
>
> # Create the exit button.
> my $exit_button = $mw->Button(
>     -command => sub { $mw->destroy() },
>     -text    => "Exit"
> );
>
> my $add_button = $mw->Button(
>     -command => \&new_object,
>     -text    => "Create an object."
> );

new_object() doesn't have an explicit return value (commented on below).  I'd
recommend having a look at the documentation for Button and seeing what it
requires.  Having an explicit return value won't change the code here though.

> $exit_button->pack( -side => 'bottom' );
> $add_button->pack();
> MainLoop;
>
> ##################################
>
> 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
>
>     # Add Labels to window
>     $tl->Label( -text => "Name:" )->grid( -row => 0, -column => 0 );
>     $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
>     );
>
>     # Create an exit button
>     $tl->Button(
>         -text    => "Exit",
>         -command => sub { $tl->destroy() }
>     )->grid( -row => 20, -column => 0 );
>
>     # Update the status every 5 seconds.
>     $tl->repeat( 5000, sub { $object->update_status() } );
>
> }

This subroutine doesn't appear to return anything.  Which of course means it
returns whatever the return status of :

	$tl->repeat( 5000, sub { $object->update_status() } );

is.  I'd suggest explicitly returning nothing:

	return;

or explicitly returning that return status:

	return $tl->repeat( 5000, sub { $object->update_status() } );

so that your future  maintainer knows what's supposed to happen.


I don't really know what's causing your issue regarding $object not being
cleaned up, but I suspect it's something to do with the answer Toby's just
given.  :)

All the best,

	J

-- 
   ("`-''-/").___..--''"`-._          |  Jacinta Richardson         |
    `6_ 6  )   `-.  (     ).`-.__.`)  |  Perl Training Australia    |
    (_Y_.)'  ._   )  `._ `. ``-..-'   |      +61 3 9354 6001        |
  _..`--'_..-_/  /--'_.' ,'           | contact at perltraining.com.au |
 (il),-''  (li),'  ((!.-'             |   www.perltraining.com.au   |


More information about the Melbourne-pm mailing list