Quoting Ovid <[EMAIL PROTECTED]>:
--- Shawn Hinchy <[EMAIL PROTECTED]> wrote:
Hello all,
I am writing many cgi scripts and need to have the same variables
included in each of them. I was going to put all these 'global'
variables in a separate file that could then be included in the top
of each cgi script.
I've seen people do this many times and it leads to clunky,
hard-to-debug systems. Globals should be avoided. Because they wind
up being spread throughout your code, it's easy for them to get altered
in one spot and not be able to figure out who altered them. Plus,
programmers can sometimes get confused about where those variables come
from, making bugs with them more difficult to figure out. Also, any
functions which rely on the existence of globals becomes harder to
refactor/use (e.g., moving it to a module which doesn't have the
globals causes things to break).
Sometimes you *do* have data which everything needs to know about.
Here are some suggestions:
Thank you Mumia and Ovid. I appreciate both of your responses. I
agree with you Ovid, you make some very good points. The point I
forgot to include is that these variables are actually
configuration-type constants. I misnamed them by calling them
variables.
1. Put those variables in constants or use the 'Readonly' module from
the CPAN.
2. If a function needs one of them, pass it as an argument.
3. Maybe put the variables in a module where you need to explicitly
request them via Exporter.
4. Alternately, do number 3 with a config file.
I think maybe the best solution may be to use the Readonly module. It
was unclear to me, however, exactly how to use it from the readme.
I'll have to play around with it.
I have been avoiding modules because they seemed to complicate things
a bit and I guess I don't know exactly how they work. Besides, if I
make a module, don't I have to install it? I don't think I have
access to install my own modules on my hosting server. I guess it's
time to do some more reading...
To include the subroutines I do this:
require './utilities.pl';
This is Perl 4 syntax. Actually, it's Perl 3. Please don't use that.
http://www.oreillynet.com/onlamp/blog/2006/08/please_stop_using_perl_3.html.
I know there's still a lot of stuff out there which teaches that and
I'm sorry you've learned from that, but the sooner you avoid that, the
better.
In the utilities.pl file I have this:
#!/usr/bin/perl -wT
sub foo {}
1;
Rename that to something like 'My::Utilities' and try giving Exporter a
try, or any of its competitors. Here's an example:
package My::Utilities;
use strict;
use warnings; # if your version of Perl supports it
use base 'Exporter';
use vars qw(
@EXPORT_OK
$BAD_GLOBAL_VAR
some_sub
);
@EXPORT_OK = qw(
$BAD_GLOBAL_VAR
COMPANY_NAME
some_sub
some_other_sub
);
$BAD_GLOBAL_VAR = 'try to avoid globals';
use constant COMPANY_NAME => 'Acme, Inc';
sub some_sub {}
sub some_other_sub {}
sub cant_get_exported {}
1;
And in the calling code:
#!/usr/bin/perl -T
use strict;
use warnings;
use lib 'path/to/your/modules';
use My::Utilities qw(COMPANY_NAME some_sub $BAD_GLOBAL_VAR);
With that, you have cleaner namespaces. You only pollute your
namespace with the specific subroutines or constants you're asking for.
It's obvious where things are coming from.
Is that a package or a module? I will give that a try after doing a
little more reading.
One problem with 'utilities' modules is that they tend to get very
bloated and programmers start shoving a bunch of stuff in them with no
rhyme or reason. Then, when you do "require './utilities.pl'", you
wind up getting a bunch of extra subroutines and if you make the
mistake of reusing *any* subroutine name in any of your files, you can
get very mysterious errors, particularly if you forget to turn warnings
on (which, to your credit, you did not :)
I've worked on systems like this and they're not fun. I recently had a
problem on a legacy system like this where I found a sub not declared
in the code. Then I found it was not declared in any of the code which
was 'require'd. Then I found it wasn't in any of the modules *they've*
required. I found it in a module which one of the *last* one's
required. Of course, I first tried grepping through the code, only to
find that the function name in question was reused in a number of
places, so that didn't help, either. It was very frustrating to work
on. The system uses some of the "features" you're asking for help
with. Please don't make the same mistakes :)
Cheers,
Ovid
Thank you Ovid, I appreciate you taking the time to respond.
Hopefully someone else will learn from my question as well.
So, knowing that I am trying define system-wide constants, would you
personally recommend the Readonly module or to use my own module or
package? I need the constants to be available to multiple scripts.
Thanks!
Shawn
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>