Re: Programming style: using Classes or inline
- From: muppet <scott asofyet org>
- To: David <dbree duo-county com>
- Cc: gtk-perl-list gnome org
- Subject: Re: Programming style: using Classes or inline
- Date: Thu, 16 Mar 2006 20:16:12 -0500
On Mar 16, 2006, at 2:30 PM, David wrote:
On Thu, Mar 16, 2006 at 09:52:20PM +1300, Grant McLean wrote:
On Wed, 2006-03-15 at 21:13 -0600, David wrote:
[...] "use strict" and separate files.
No, that's right, before you added 'use strict' all your variables
were
global variables. When you declared the variables with 'my', you
restricted their scope to the block they appeared in (eg: a
subroutine)
or to the file if they weren't in a block.
What came as a surprise to me was that I couldn't have global
variables.
Again, I'm quite new to Perl and some of the rules are a bit
unexpected.
"strict" doesn't prevent you from having globals. What it does is
require that you use either fully-qualified package names or
lexically-scoped variables.
Without "strict", any variable name is legal, and the scope is global
by default. This was and is very handy for command-line one-liners
and other quick hacks, but in Real Code is Very Dangerous. The most
common case is that you can misspell a variable name and never know
it until you've spent far too long tracking down the resulting logic
bug.
So, "strict" essentially makes you declare your variables. With "my"
you create a variable which is visible only within the containing
lexical scope (the file, package, or block). With "our" you declare
a variable that lives in this file but is visible to anyone who knows
the package name. You can also say "use vars qw($foo @bar)" to
achieve the same effect as "our $foo; our @bar;". To refer to these
variables from other packages you must either refer to them with
fully-qualified package names (e.g. $OtherPackage::foo) or set up the
host package as an Exporter and import them into other packages.
All of this is documented in perl's online manual.
And, actually, i hesitate to mention all of this because globals
really are not good things to use. They limit the ability of your
packages to scale to multiple instances and tend to cause spaghetti-
like interdependencies.
Avoid globals.
Learn to create classes. Perl makes it very easy. Once you
understand classes, there's a slight change in initialization style
to start creating subclasses of Glib::Objects so that you can create
your own widgets. Here's a write-up that contrasts normal perl
classes and Glib::Object-style classes.
http://gtk2-perl.sourceforge.net/doc/subclassing_widgets_in_perl.html
if I were to adapt some of the routines to Classes, what's
normally best - separate files or a single file?
You can do either. It's perfectly reasonable to declare multiple
classes in a single file.
With the above question, I meant keeping the classes in the same
file as
the mainline code. I know that in your tutorial, you stated that
while
developing your project, you kept separate files for the classes
and the
mailine code, but that sometimes it was advantageous, especially after
development was complete, to merge them all into one file.
Whether to use one file or a bunch of files really depends on how the
code will be used. When i have something that i want to deploy
easily, i like to have all the classes in a single file so that the
application consists of just one file. If i'm reusing code, i'll
create installable modules.
An important thing to remember when placing a bunch of classes in one
file is that execution order still matters. When using "require" or
"use", your whole pm file will be parsed and then executed. If you
have all the classes in one file, all of the code will be parsed, but
whether it will be executed depends on the position in the file. To
wit:
-=-=-=-=-=-
#!/usr/bin/perl -w
package ThingOne;
print "initializing ".__PACKAGE__."\n";
our $stuff = 42;
sub new { return bless { stuff => $stuff }, $_[0]; }
package main;
# here is some driver code.
use strict;
foreach my $class (qw(ThingOne ThingTwo ThingThree)) {
my $thing = new $class;
print "$thing\->{stuff} = $thing->{stuff}\n";
}
package ThingTwo;
print "initializing ".__PACKAGE__."\n";
our $stuff = 42;
sub new { return bless { stuff => $stuff }, $_[0]; }
package ThingThree;
print "running in ".__PACKAGE__."\n";
our $stuff;
BEGIN {
print "initializing ".__PACKAGE__."\n";
$stuff = 42;
}
sub new { return bless { stuff => $stuff }, $_[0]; }
-=-=-=-=-=-=-=-=-
This prints out the following:
$ perl single-file.pl
initializing ThingThree
initializing ThingOne
ThingOne=HASH(0x9339d20)->{stuff} = 42
Use of uninitialized value in concatenation (.) or string at single-
file.pl line 12.
ThingTwo=HASH(0x9339d98)->{stuff} =
ThingThree=HASH(0x9357080)->{stuff} = 42
initializing ThingTwo
running in ThingThree
Figuring out why is left as an exercise for you. :-)
So, you then get to decide whether you want your main driver logic at
the top or at the bottom of the file.
The perlmonks.org web site is a good place for questions and quick
feedback too.
Yes, that would be a more apropriate place. I do realize that this
question _was_ a bit OT for this list.
If everything was on-topic life would be quite boring. But i do try
to spare y'all the tales of what crazy things my kids have done each
day. =)
--
"that's it! you're a genius!" "yes. that's what i think. do you
think i deserve a raise?"
- dialogue from 'Godzilla versus Mothra', 1964
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]