Hello -
I have a series of scripts and modules that I will self install, creating directories within the cgi-bin directory. The structure looks like this:
|-- Base cgi-bin -- DsgnGrp --| |-- Utilities
DsgnGrp contains the scripts that call modules in Base and Utilities. Base contains modules that fulfill basic functions like database access, file management, etc. Utilities contains modules that do more specific things like validate email addresses, validate credit cards, validate form submissions, etc. The problem I'm having is in getting modules in Utilities to find modules in Base. I've tried this in a Utilities module:
I am wondering if this is so complicated because of a poor design decision. For me it doesn't make sense for a module to know anything about where it is installed or where any other modules are installed, just that they are installed and callable. Otherwise encapsulation and modularization break down. I would re-think the module layout and update the scripts so that they determine where a Perl module is installed, then you can move your FindBin code into the script and include as many 'use lib' lines as you wish. This may also help your development cycle, including testing and development vs. production environments.
use strict; use FindBin qw($Bin); # Locate the path to this script use lib "$Bin/../Base"; # Set the path to the Base directory in the @INC use DGObjectManager; # Creates and validates new objects
and that works for that module. The problem arises when I try to use two modules out of Utilities in the same script call. For instance, if I need to validate an email address and a credit card number. According to the Perl 5.8 documentation for FindBin on CPAN:
"If there are two modules using FindBin from different directories under the same interpreter, this won't work. Since FindBin uses BEGIN block, it'll be executed only once, and only the first caller will get it right. This is a problem under mod_perl and other persistent Perl environments, where you shouldn't use this module. Which also means that you should avoid using FindBin in modules that you plan to put on CPAN. The only way to make sure that FindBin will work is to force the BEGIN block to be executed again:
delete $INC{'FindBin.pm'}; require FindBin;"
This form of the call:
use strict; delete $INC{'FindBin.pm'}; require FindBin; use lib "$FindBin::Bin/../Base"; # Set the path to the Base directory in the @INC use DGObjectManager; # Creates and validates new objects
fails in Perl 5.6 with the error:
Can't locate DGObjectManager.pm in @INC (@INC contains: /../Base /usr/lib/perl5/5.6.1/i686-linux /usr/lib/perl5/5.6.1 /usr/lib/perl5/site_perl/5.6.1/i686-linux /usr/lib/perl5/site_perl/5.6.1 /usr/lib/perl5/site_perl .)
You can see that the Base directory is there, but the form is different from the "use" call which takes the form:
/home/rongoral/uponthemountain-www/cgi-bin/DsgnGrp/Utilities/../Base
Modifying the calls to DGObjectManager to "DsgnGrp/Base/DGObjectManager" or "Base/DGObjectManager" does not alleviate the issue.
I am getting hopelessly confused here. Any help would be greatly appreciated.
I would re-think your structure, this is very non-standard and as the docs indicate, probably not for the faint of heart. As a suggestion you might consider setting up a single directory where your home grown Base and Utilities modules live, then just call them by name under that single directory, for instance:
/www/cgi-bin/lib/DsgnGroup/Base/ObjectMgr.pm /www/cgi-bin/lib/DsgnGroup/Utilities/DB.pm
Then in your scripts you have,
use lib qw( /www/cgi-bin/lib ); use DsgnGroup::Base::ObjectMgr; use DsgnGroup::Utilities::DB;
Alternatively you could boil down to a single 'use' that pulls in the various sub-modules.
What I am prone to do these days is have the following:
/httpd/domains/lib /httpd/domains/danconia/lib /httpd/domains/danconia/cgi-bin /httpd/domains/domain2/lib /httpd/domains/domain2/cgi-bin
Then within a script in either cgi-bin I have the following:
use FindBin; use lib "$FindBin::Bin/../../lib"; use lib "$FindBin::Bin/../lib";
Each site can then use any libraries that are generic to both, and I can have domain specific libraries override server wide libs since they get seen first, just my current thoughts, this has some flaws too...
HTH,
http://danconia.org
-- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>