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

Hello dear fellow monks,

I have a problem with using a module under VMS, but my problem is not necessarily due to VMS, but maybe to me not understanding fully the way the use lib qw/path_to_my_modules; and use mymodule; work.

Just to be clear, I have written at least two dozens other modules (mostly for various brands of Unix) and always succeeded to use them, but this is my first try under VMS and I am stuck.

I wrote a relatively complex application, which includes 3 large Perl programs, some DCL command files (equivalent of shell scripts under Unix) launching proprietary software applications for database access, etc. Just to give the overall context, in total about 30 different programs working together, but that's not my problem

For the three Perl programs that I wrote (which refactor and replace about 25 other existing programs), I also wrote a module containing some helper functions and some hashes of hashes describing the environment (IP addresses of the various platforms, batch queue name, and so on).

I originally wrote my programs and the common module all in my home directory (SYS$LOGIN under VMS), and got to the point where the whole thing is compiling and working exactly as expected.

The (simplified) syntax for the top pragmas was essentially as follows:

use strict; use warnings; use VMS_UTILS qw (wait_for log_info check_valid_date (...) say); # ...
Notice that I have a say function defined in this module; on VMS, I am stuck Perl 5.8, so I wrote my own say sub because it is quite practical, this will be important below.

But I then needed to prepare for the production environment. Programs and modules should not be in the private home directory of a user, but in special directory called programs or PROGRAMS, VMS being case insensitive (it's not the real name, but let's say that's what it is), which is a logical name (i.e. an environment variable in Unix terms) pointing to a directory.

So, I moved the Perl programs and my module to the PROGRAMS directory and modified the Perl program as follows:

use strict; use warnings; use lib qw/programs/; # also tried PROGRAMS, just in case, but equival +ent result use VMS_utils qw (... say); #using VMS_UTILS also does not change the +result
And I got the following message:
Can't locate VMS_utils.pm in @INC (@INC contains: programs perl_root:[ +lib.VM S_IA64.5_8_6] perl_root:[lib] perl_root:[lib.site_perl.VMS_IA64] perl_ +root:[lib. site_perl] /perl_root/lib/site_perl .) at ...
So, I thought, OK, may be Perl cannot resolve the programs symbol (it normally can without having to use the %ENV hash, because VMS does the transcription under the scene without Perl knowing, at least that's what I understand, but, maybe, in a use lib pragma it does not work), so I changed the use lib pragma to the content of the programs symbol.

And that's where the result is really puzzling to me:

# use lib ('DISK$ECD:[DMC]'); # does not work use lib 'DISK$ECD/DMC/'; # does not work either use VMS_UTILS qw (...);
Now, I get a totally different type of errors:
perl -c programs:ALL_CRA_CHCOEX1262.pl String found where operator expected at ecd_programs:all_cra_chcoex126 +2.pl line 19, near "say "Environnement $plt incorrect !!"" (Do you need to predeclare say?) ... many other compile errors
The compiler did not fail on loading the module, but failed on using the say subroutine defined in aforesaid module.

Basically, to make things simple, what I do not understand is this:

- In one case, the program does not find the module, so that compilation fails. Fair enough.

- In the other case, it seems that the compiler was able to find the module, but apparently did not load it correctly. And everything works correctly if all the software components are in the home directory of the user.

Update: fixed a couple of formatting issues and typos. Also, sorry if this is long, I tried to explain as much as possible the context.

Replies are listed 'Best First'.
Re: Solved - Using a module under VMS
by Laurent_R (Canon) on May 28, 2015 at 08:04 UTC
    Just in the context of having answered Anonymous Monk above and reformulated my question, I found the origin of the problem.

    While trying to solve my first problem (the path to the module not being recognized), I made the silly mistake of changing:

    use VMS_utils;
    to
    use VMS_UTILS;
    thinking that I would thus give Perl a better chance to find the module (VMS file names are all uppercase). But that was a mistake, because in my module I have:
    package VMS_utils;
    So what happens with this, is that, indeed, Perl is able to load the module successfully, but it no longer recognizes the package, because it is declared with some lower case letters within the module and I invoked it with all upper case letters in the program.

    Sorry to have bothered you with my silly mistakes, dear fellow monks, I should have found by myself, but I guess my mind was just too confused yesterday evening after having tried at least three dozen alternative syntaxes.

Re: Using a module under VMS
by Anonymous Monk on May 27, 2015 at 22:09 UTC

    (Disclaimer: No experience on VMS, just throwing some ideas out there)

    See "Caveats" in lib:

    In order to keep lib.pm small and simple, it only works with Unix filepaths. This doesn't mean it only works on Unix, but non-Unix users must first translate their file paths to Unix conventions.

    # VMS users wanting to put [.stuff.moo] into # their @INC would write use lib 'stuff/moo';

    Or, you could try fiddling with @INC yourself? BEGIN { unshift(@INC, 'DISK$ECD:[DMC]') } ?

      Thank you for your answer, Anonymous Monk, but yes, I have figured out this caveat on the lib pragma, which is why I tried both these syntaxes:
      # use lib ('DISK$ECD:[DMC]'); # does not work use lib 'DISK$ECD/DMC/'; # does not work either
      Although the origin of my problem really seems to have something to do with VMS specificities, my question is really more general and not VMS specific: in one case, Perl does not find the module and compilation fails on the use VMS_utils , which is what I would expect. But once I tried to fix that by changing the use lib qw/.../ clause, I no longer have an error on loading the module, so I would assume Perl succeeded to load it, but compilation fails on using the subroutines (e.g. the say function) defined in this module.

      So my more general question is: are there some conditions under which Perl does not fail on the use statement loading a module but still does not apparently load the subroutines defined in the module. Knowing that my module is apparently correct, since everything works correctly when both the programs and the module are in the same directory.

      Please also note that I have also tried, among many other things, to copy my module into one of the @INC paths, but I still get the compilation error on the use of subroutines defined in the module. This is really puzzling my mind.

        Hi , another AM with another suggestion, try like this

        perl -Ivmsdirhere -MModulename -e 1

        If you can't get that working, try

        require 'vmsdirhere/Modulename.pm';

        An error should pop, and you should be able to figure it out ... do you have use feature qw/ say /; or equivalent (if thats the issue)?