0

I'm trying to give a "human readable message" for an application if there's missing modules upon running the script. However I've stumbled upon an issue when it comes to loading modules with qw.

I've tried the following:

use strict;
...
if ( ! eval { require Proc::Daemon;1; } ) {
    push (@install_packages, "Proc::Daemon"); 
} else {
    Proc::Daemon->import(qw( SOCK_STREAM SOMAXCONN ));
}

However it fails

Bareword "SOCK_STREAM" not allowed while "strict subs" in use at ./revmon.pl line 144.
Bareword "SOMAXCONN" not allowed while "strict subs" in use at ./revmon.pl line 144.

Using use obviously doesn't work as it will give the normal error-message

Can't locate Proc/Daemon.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .)
BEGIN failed--compilation aborted at ./revmon.pl line 11.

Adding * to the bareword doesn't help much either since it's only used once which will throw another error with use warnings;

Is there same way to work around this to get the BAREWORDS working properly when the module can be loaded successfully?

user2108948
  • 173
  • 1
  • 7
  • 1
    I can't reproduce this. What Perl version/platform are you on? Does it work if you call `Proc::Daemon->import("SOCK_STREAM","SOMAXCONN")` ? – mob Jul 24 '13 at 22:38

2 Answers2

1

The problem is that you load the module after you compile the code that uses it. When you do that, you can't use functions imported from the module as barewords.


Using SOCK_STREAM() and SOMAXCONN() will postpone the check to run-time.

Or

BEGIN {
    if ( eval { require Proc::Daemon } ) {
        Proc::Daemon->import(qw( SOCK_STREAM SOMAXCONN ));
    } else {
        push(@install_packages, "Proc::Daemon"); 
        *SOCK_STREAM = sub () { die };
        *SOMAXCONN   = sub () { die };
    }
}

Or move the stuff using Proc::Daemon to its own module

if ( eval { require Proc::Daemon } ) {
        require App::Proc::Daemon;
        $handler = App::Proc::Daemon->new();
    } else {
        push(@install_packages, "Proc::Daemon"); 
    }
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
-1

For use at run-time, use string-eval, not block-eval, because any use statement encountered at compile-time will be evaluated at compile-time

if (! eval "use Proc::Daemon qw(SOCK_STREAM SOMAXCONN); 1") { ... }

Related questions:

How can I check if I have a Perl module before using it?

Perl - eval not trapping "use" statement

Community
  • 1
  • 1
mob
  • 117,087
  • 18
  • 149
  • 283