Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi, Currently, i have a perl file "A.pl" that has all the functionality that is needed. It also has the pre-defined arrays and hashes declared. Now this file has become too large and has become unmodular. 1. How can i organize this file in a modular way? 2. Can i put all the array and hash definitions into one more file "B.pl" and include it in A.pl as in 'C' language header files? If so, how do i include it? thanks a lot,

Replies are listed 'Best First'.
Re: including another perl file
by hiseldl (Priest) on Jun 02, 2003 at 13:09 UTC

    B.pl would have to contain valid perl code, and then in your A.pl you could...

    eval { require "B.pl"; } if ($@) { # deal with error } ...
    ...this will make all your variables in B.pl available in A.pl.

    Cheers!

    --
    hiseldl
    What time is it? It's Camel Time!

Re: including another perl file
by Juerd (Abbot) on Jun 02, 2003 at 13:25 UTC

    The only way to literally include a file is to eval its contents:

    eval do { local $/ open my $fh, '<', 'B.pl' or die $!; readline $fh; } +;
    Use require and use only with modules (those .pm thingies that have their own packages), because require only loads once and this WILL bite in any persistent environment.

    do FILENAME is great, but many people expect lexicals to be shared, so I only recommend eval STRING for file inclusion now. In my mind, there are two ways of programming with multiple files:

    1. Dirty: literal file inclusion. Dirty anyway, so eval STRING is okay;
    2. Clean: generalized modules, used as such. No two files use the same package.

    Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

      require only loads once and this WILL bite in any persistent environment.
      $ echo 'print 1;' > test.pl $ perl -le'{ local %INC; require "test.pl" } require "test.pl";' 1 1
      Update: that should be local %INC = %INC; in fact.

      Makeshifts last the longest.

        local %INC;

        Good point, but I don't think many people will remember to do that :)

        Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

Re: including another perl file
by BrowserUk (Patriarch) on Jun 02, 2003 at 14:06 UTC

    There's no need for eval evil or source filter trickery. The simplest method for this is to use perl's own include mechanism.

    It's named do 'file;.

    included.pl

    our %b; @b{'a'..'z'} = 1 .. 26;

    #! perl -slw use strict; use Data::Dumper; do 'included.pl'; ## Perl's include. our %b; print Dumper \%b;

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


Re: including another perl file
by broquaint (Abbot) on Jun 02, 2003 at 13:32 UTC
Re: including another perl file
by rnahi (Curate) on Jun 02, 2003 at 14:16 UTC
Re: including another perl file
by DrHyde (Prior) on Jun 02, 2003 at 13:31 UTC
    You've already been told about the eval/require dance, which I won't repeat. Instead, I'll tell you about a similar problem I had recently and how I solved it. It involves an app I'm writing for the Palm, which needs a lot of data to work with. I'm writing my app in C, but fetching the data and mangling it into an appropriate format using perl.

    I did briefly consider using my perl script to mangle the data into C source code and then #include it into my C program. That would certainly make the task easier as I wouldn't have to mess around with databases. However, it would mean that users would have to rebuild the program to update the data, and would also lead to resource "issues". Instead, I did The Right Thing, and my perl script instead spews out a few PDBs using Palm::Raw (which whilst it is listed on CPAN and downloadable through a browser, CPAN.pm didn't want to install for me, but that's irrelevant here). And my C code opens those databases and uses them.

    Of course, most of the reasons for me using PDBs are irrelevant to your perl program, but you might like to consider using something like dbm files instead. It seems somehow more elegant :-)