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

I have two versions of a set of scripts (a development version and a production version) running in the same cgi directory. The naming convention is:
MainProg.pl LayerA.pm LayerB.pm LayerC.pm MainProg2.pl LayerA2.pm LayerB2.pm LayerC2.pm
Each file (except the bottom ones) contains a 'use LayerX.pm' (or whatever) line near the top. The development files of course each say 'use LayerX2.pm'.

When I shift the development version of a file or two over to the production set, I just drop the '2' from the file name and adjust the 'use ...' line. This works fine. But it's a nuisance and occasionally I flub it.

So I'd like to read the name of the current file, check for a '2' in the filename and then 'use ...' the appropriate next lower module.

'use' requires a bareword, so I can't say 'use LayerB$version'. What are the implications of:

if ($version == 2) { use LayerB2; } else { use LayerB; }
Is there any downside to this? Seems like there are likely some compile-time vs. run-time issues.

Is there some other recommended method?

Replies are listed 'Best First'.
Re: Conditional use of 'use'
by bikeNomad (Priest) on Jun 12, 2001 at 09:04 UTC
    Since use module is the same as
    BEGIN { require module }
    , you could do something like:
    BEGIN { my $version = (($0 =~ /2(?:\.pl)?$/) ? '2' : ''); require "LayerB${version}.pm"; }
    If you are using the form use module LIST you'll need to call import:
    BEGIN { # set $version based on $0 require "LayerB${version}.pm"; "LayerB${version}"->import(qw(A B C)); }

    update: added import part, cleaned up $version setting

      Camel 3, p. 822 (which I had already consulted), says: BEGIN { require MODULE; import MODULE LIST; } What about the import? Needed? Not? The modules are pure OO. And no @EXPORT (if that is relevant).
        You've asked the right question. If you only ever use the OO interface and if you don't export anything from the modules, you don't need to import anything explicitly.

        Then you can just do:

        if ($version == 2) { require LayerB2; } else { require LayerB; }

                - tye (but my friends call me "Tye")
Re: Conditional use of 'use'
by pmas (Hermit) on Jun 12, 2001 at 09:13 UTC
    Try       use lib xxx;

    It will change search directory.

    How to do that: All programs will contain line

    use lib_config;

    You will create two copies of file lib_config.pm.

    In production, file lib_config.pm will contain:       use lib prod;,

    but in development it will contain       use lib devel;

    This way, you can copy a program from devel to prod without any changes. lib_config.pm will contain differences.

    Hope this helps and I understood you properly.

    pmas

    To make errors is human. But to make million errors per second, you need a computer.

Re: Conditional use of 'use'
by busunsl (Vicar) on Jun 12, 2001 at 10:33 UTC
    TIMTOWTDI:

    You can run the script with the -P flag.
    This will start the C Preprocessor, which can handle that sort of stuff for you.

(tye)Re: Conditional use of 'use'
by tye (Sage) on Jun 12, 2001 at 19:53 UTC

    Since use happens at compile time and both the if and else parts of your code get compiled, you proposed code has the same effect as:

    use LayerB2; use LayerB;
    which probably won't work very well.

    You can get around that with:

    BEGIN { if ($version == 2) { eval "use LayerB2"; } else { eval "use LayerB"; } die $@ if $@; }

    I'd actually suggest changing LayerB.pm to support both environments so that your staging environment is more likely to very closely match your production environment. Something like: use LayerB ( Version=>$version ); or use LayerB ( Production => 2!=$version );

            - tye (but my friends call me "Tye")
Re: Conditional use of 'use'
by jepri (Parson) on Jun 12, 2001 at 10:11 UTC
    This sounds like the perfect job for a perl script!

    (untested) #!/usr/bin/perl my %files= ( MainProg2.pl => MainProg.pl, LayerA2.pm => LayerA.pm, LayerB2.pm => LayerB.pm, LayerC2.pm => LayerC.pm, ); foreach (keys %files) { open(IN, "<$_"); open(OUT,">$files{$_}"); while (my $line=<IN>) { foreach (keys %files) { $line=~s/use $_/use $files{$_}/g; } print OUT $line; } close IN; close OUT; }

    You should be able to adapt that to your needs.

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.