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

Hi Monks,

I'm writing a number of scripts which hit LDAP databases, and I want to prefer but not require SSL in my LDAP connections. In simple cases, eval { require Net::LDAPS; } works, but if the Net::LDAPS module exists but does not compile, the eval still returns correctly.

For instance, say the IO::Socket::SSL library is missing, or the libssl library is missing, but Net::LDAPS is there. In that case, the eval returns correctly but any attempt to actually use Net::LDAPS fails miserably.

How can I test for existence and success of a module?

I know the correct solution is to not have Net::LDAPS unless it works correctly, but that doesn't really solve the original problem. Or rather, the real correct solution is to use start_tls on Net::LDAP, but the server I'm using (Netscape 4.x) doesn't support TLS...

Replies are listed 'Best First'.
Re: Testing sub-module existence
by broquaint (Abbot) on May 07, 2002 at 16:18 UTC
    Check out the $@ variable which contains the contents of any errors incurred while running eval()
    # foo.pm package foo; sub 123 { print "this is an invalid sub name" } qq(The End); # script.pl eval "require foo;"; die("ack - $@") if $@; __output__ ack - syntax error at foo.pm line 5, near "qq(The End)" Compilation failed in require at (eval 1) line 1.

    HTH

    _________
    broquaint

      Hmm, this worked the first time, but fails the second time. That is, imagine the following situation (which roughly mirrors my own):

      sub connect { if (eval { require Net::LDAPS; } and ! $@) { $ldap = Net::LDAPS->new($_[0]); } else { $ldap = Net::LDAP->new($_[0]); } return $ldap; } sub auth { $ldap = connect($_[2]); $ldap->bind($_[0],$_[1]) and return $ldap; } ($dn,$pass,$host) = @ARGV; auth($dn,$pass,$host) or die "auth failed\n"; $ldap = connect($host); $ldap->bind($dn,password=>$pass) ...

      In my case, the auth and connect routines are both in a library which I use for a lot of different scripts, so I needed them to be generically useful; I can't always guarantee that the connect routine won't be run multiple times in the same script.

      If I only run connect once, everything works fine, but if I run it twice, then the second time it doesn't record a failure, because Net::LDAPS has already failed to compile but is registered in %INC anyway.

      Is there some kind of way to collect this information, or am I going to have to store a $::HAVESSL variable or something, which I hate?

      And thanks for the quick response.

Re: Testing sub-module existence
by samtregar (Abbot) on May 07, 2002 at 18:36 UTC
    Assuming the module you're using has a $VERSION you could do:
    eval { require Foo::Bar }; die "Foo::Bar didn't load right, man" unless $Foo::Bar::VERSION;

    -sam