Will This Madness Never End?

mako132 on 2002-07-09T21:16:19

Jeeze, I spend as much time futzing with Perl module installs as I do coding. What I need is something that shows me what modules (and version) my script is using so that I figure out why the @##$^#$^ thing works like a charm on one OS but barfs 'Use of uninitialized value ...' in another.


how about this?

wickline on 2002-07-10T13:46:43

> What I need is something that shows me what
> modules (and version) my script is using

how about which lib directory those modules are being
loaded from? The following END block will do all of
that for you. Note that you may need to have it print
to a log file or something instead of the currently-
selected filehandle. ((Code at end of this post.))

You can create a trivial test script that has just a
shebang line, then use's several modules, then has
this END block. It should spew your info to STDOUT.

Once you've got it producing output for each instance
of your script, just diff the two to find what's up.

If there *are* no differences, then at least you've
ruled out module versions as an issue. You still have
platform issues, perl versions, webserver and webserver
congig issues (if this is a CGI script), %ENV issues,
permissions issues, etc.

Good luck  :)

-matt

END { no strict 'refs';
    for my $k ( sort keys %INC ) {
        ( my $module = $k ) =~ s{[:/\\]}{::}g;
        $module =~ s{\.pm$}{};
        my $version = ${"${module}::VERSION"};
        if ( defined $version ) {
            $version = "\$${module}::VERSION = $version\n";
        } else { # maybe they didn't use ALLCAPS
            my @found = (
                map { defined ${"${module}::$_"}
                     ? qq(\$${module}::$_ = ${"${module}::$_"}) : ()
                }
                grep { m/^version$/i }
                keys %{"${module}::"}
            );
            $version = !@found
                ? "($module  version number not found)\n"
                : join( "\n", @found );
        }
        # if you want, print this to a log file instead:
        print "$version $module  loaded from  $INC{$k}\n\n";
    }
}

Re:how about this?

mako132 on 2002-07-10T15:08:32

Yow! Thanks! I'll try it. My first guess was some BEGIN block vodoo (but I hadn't yet given it real thought).

I'm going to rig up some Test:: stuff also. I tend to develop in FreeBSD and Linux and then go production on Solaris so I'll write me up a good test script...

Re:how about this?

wickline on 2002-07-10T21:46:22

> My first guess was some BEGIN block

You could put that in a BEGIN block instead of an END block
if you wanted. It would still work... however, it would miss
two classes of modules:

    1) any modules use()'ed after the BEGIN block

    2) any modules require()'ed rather than use()'ed
       whether before or after the BEGIN block or in
       some other module

By sticking it in an END block, you catch both of the above
classes of modules. Nothing's perfect though... either way
will miss modules require()'ed in later END blocks or funky
cases where your code might have monkeyed with the symbol
table (probably not likely to happen by accident  :)

-matt