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

Dear monks,

I cooked up a small Perl application consisting of a script, which is based on a Module (with some submodules), like so (much simplified)

script:
#!/usr/bin/perl use My::Module;
My/Module.pm:
package My::Module; ...
My/Module/Submodule.pm:
package My::Module::Submodule ...

Now, to offer a staging version of all that, I'd like to let Makefile.PL a "staging version" of all that. Assume $VERSION==0.9, then I'd like to have:

script:
#!/usr/bin/perl use My::Module-0.9;
My/Module-0.9.pm:
package My::Module; ... My/Module-0.9/Submodule.pm: <code> package My::Module::Submodule ...
Is that possible with Makefile.PL? Is that even a good idea? Where do I start? What alternatives do I have?

Replies are listed 'Best First'.
Re: Appending $VERSION to package name in Makefile.PL
by Eliya (Vicar) on Apr 18, 2012 at 17:39 UTC
    ... Is that even a good idea?

    Personally, I wouldn't put the version in the module name/path.  In the long run, keeping all code in sync that references the module gets a little unwieldy for my taste, and without any real benefit, AFAICT.

    I'd rather use a version control system to quickly check out / switch between multiple versions — if that is the idea.

    Or, if you prefer multiple physical subdirectories named after the versions, put another directory above the root of the module name space, i.e. .../0.9/My/Module/Submodule.pm, and then adjust PERL5LIB or similar to point to the respective toplevel directory.  Sure, that doesn't allow things like My-1.1/Module-0.9/Submodule-2.3.pm, but I'm not sure if that's a good idea anyway :)   In case you really want the latter, you could manage a bunch of symlinks (if your file system supports them) pointing to the desired versions, so you can keep the version numbers out of the use statements...

    P.S.: use My::Module-0.9 wouldn't work for syntactial reasons — you'd at least need something like My::Module0_9.

      Thanks, Eliya for your insights.
      In the long run, keeping all code in sync that references the module gets a little unwieldy for my taste

      That's why I wanted Makefile.PL to do the dirty work for me.

      Of course, I'd strive for it writing the right incantations into the script such that it finds "its" modules.

      I'd rather use a version control system to quickly check out / switch between multiple versions — if that is the idea.

      I slowly notice how sloppy I was in describing my problem.

      The script is a network server, and I wanted the alternative ("staging") version to provide a new version of the service (perhaps on a different port) for the users to test, without disrupting the current (stable) service.

      Or, if you prefer multiple physical subdirectories named after the versions, put another directory above the root of the module name space, i.e. .../0.9/My/Module/Submodule.pm

      That's it! This schema makes much more sense.

      Now how would I get MakeMaker to do that for me (e.g. saying

      perl Makefile.PL STAGING=yes
      would
      • rename the executable to script-$VERSION
      • install the modules to $LIBDIR/$VERSION
      • work some magic in the script to point to above lib dir
      I have some ideas about point 3 above (I'd have to provide a script template, script.PL which would write out the script with some substitutions), but I'm somewhat lost on 1 and 2.

      Sure, that doesn't allow things like My-1.1/Module-0.9/Submodule-2.3.pm, but I'm not sure if that's a good idea anyway :)
      No, I'm not *that* crazy ;-)
      P.S.: use My::Module-0.9 wouldn't work for syntactial reasons — you'd at least need something like My::Module0_9
      You are absolutely right. The idea you've given to me above is far better, anyway. Thanks again, I'm a step closer now :-)

        The script is a network server, and I wanted the alternative ("staging") version to provide a new version of the service (perhaps on a different port) for the users to test, without disrupting the current (stable) service.

        Use a layout like this:

        bin/myscript.pl bin-testing/myscript.pl lib/My/Module.pm lib-testing/My/Module.pm

        Then, to run the stable service:

        perl -Ilib bin/myscript.pl --port=1234

        And for the testing service:

        perl -Ilib-testing bin-testing/myscript.pl --port=1235
        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'