SPUG: Interdependance of package subroutines
haircut at gmail.com
Thu May 19 13:20:48 PDT 2005
On 5/19/05, Ken Clarke <kenslinux at shaw.ca> wrote:
> Hi Folks,
> I'm building a library of subroutines, separated into functionally
> grouped packages, for use in CGI scripts and cron jobs. I'm finding that as
> the library grows more and more I want subroutines from one package to be
> available for use in another package, so I'm either calling them by their
> package qualified names [ eg my $result_hashref =
> &MyPackage::my_sub(\%sub_args); ], or if they've been imported into package
> main, directly from there [ eg my $result_hashref =
> &main::my_sub(\%sub_args); ].
> I would appreciate hearing your comments on the wisdom of this strategy
> from an architectural standpoint. Testing on various platforms shows that
> everything works as intended but I'm getting an uneasy feeling that there
> may be pitfalls which I am not seeing.
Good questions! Putting time and thought into your architectural
decisions will definitely yield benefits down the road. I apologize
ahead of time if any of this is old news, I just decided to get up on
the soapbox for a minute or two, and I'm not really sure what your
level of expertise is.
Sounds like you're making some utility packages, and your architecture
goals focus around reusability. Is that accurate?
What kinds of things are you doing? Date manipulation? Logging? Image
manipulation? Say you distribute your code. Do you intend to package
the modules you create with your scripts?
If you have some code that's useful for two or three of your personal
scripts and is machine/location/etc. dependent, just do what you're
If you've written some valuable functional unit and you're able to
generalize the code for public use, put it on CPAN. Sometimes when
preparing to do this, you'll find a good CPAN module that you can use
instead of your own code. I almost always prefer this.
If you've written some code that's useful in CGI scripts, consider
submitting a patch to CGI.pm.
How 'bout this, to help you with a specific problem, let's walk
through a specific example. If you would, please provide a sample bit
of packagable code. We can walk through some ideas about architecting
it into a reusable unit.
(begin tangential ballyhoo)
Object orientation (hereafter referred to as "OO") may also be
appropriate. Without knowing the details of what you're trying to do,
it's tough to say if something would best fit in a non-OO or OO
package. I usually look to popular modules to make these kinds of
A good example of a non-OO module is MIME::Base64. It's simple, and
doesn't seem to warrant the overhead and complexity of OO. I would
consider it appropriate to import encode_base64() and decode_base64()
into the main namespace when needed.
A good example of OO programming is LWP. LWP is very complex and has
many different layers, interfaces, and capabilities. OO seems to break
down LWP into easily understandable and reusable chunks.
Of course, one can also provide OO and non-OO interfaces, like File::Temp.
"Object Oriented Perl" by Damian Conway is the definitive guide to OO
programming in Perl.
Some folks also prefer table-oriented programming in favor of OO.
Others like to mix aspect-oriented programming with OO for
functionality that cross-cuts an application (logging, for instance).
Mixins are closely related to aspect-oriented programming. These
are all interesting topics to study when thinking about software
I'm curious, how do you go about ensuring that your packages are in
@INC? I find setting the $PERL5LIB environment variable is a fairly
clean solution, especially compared to hardcoding 'use lib ...' in
scripts using your custom libraries that aren't installed in
systemwide Perl lib directories.
Hope this helps,
Adam Monsen <adamm at wazamatta.com>
More information about the spug-list