So, I do create numerous inhouse business specific Perl modules. (I.e. not CPAN candidates, too specific for that.)
I find that a whole bunch of my modules are primarily built for providing code reuse between applications, not to provide code reuse within an application.
First choice is to use OO style modules or traditional functional style modules. I personally prefer using the OO style modules even for these kind of modules. There are several reasons for this, including consistent function call/method execution techniques, the question of name space pollution, etc. So, the choice has fallen on OO style modules in all cases concerned for this post.
As the modules, written as OO modules, are written for reuse between applications there is no logical reason to instantiate more than one object of the class within the application using the module. At the moment of instantiation an object handle is retrieved and stored.
my $handle=Module->new(); # Very classical, no surprices here.
Now the question is how to store this handle. The handle will be used between many, the majority, of the subs in the application. But not
all subs will need this object handle.
I see two classical ways of handling the handle. (No pun intended.)
- Store the handle as a global variable, accessible by all subs. (Potentially with use vars qw/$handle/; )
- Provide the handle as a parameter to all subs that will need it.
The problem with the first solution is that I have to maintain a global variable, something that I try to avoid, mainly because I dislike the usage of global variables. They tend to confuse me. And
style, of course.
The second solution means putting the handle on the call stack for almost all subs. Performance hit? Maybe, since these are apps that do a lot. And I mean
a lot.
It will also imply that a number of subs will take the handle as a parameter with the only objective to provide it to another sub, called from this sub. Not very clean at all.
I came up with the following approach:
use strict;
use warnings;
use Module;
BEGIN {
my $handle;
sub get_handle {
# Simplified for clarity.
# If handle defined, return it.
# Otherwise create it and return it.
defined($handle)||
defined($handle=Module->new())||
die("Failed to instantiate a Module object\n");
$handle;
}
}
get_handle()->method_a('parameter');
get_handle()->method_b('parameter');
exit;
Now, the result from this is that I have just hidden a global variable inside a sub. I have created a sub to get to my global object handle.
I don't use vars. I don't have a global variable in it's traditional meaning. Technically, my global variable is implemented as a function call.
All subs are available throughout the application eq 'good approach'.
No global variables are available throughout the application eq 'good approach'.
- Am I cheating myself?
- Will other developers understand what I'm trying to achieve?
- Am I really achieving something?
- Is this overkill?
- How do you handle these situations?
- Thoughts?
Everything went worng, just as foreseen.
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: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.