Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Defining a subroutine one of two ways depending on whether a package exists

by bikeNomad (Priest)
on Jun 07, 2001 at 22:25 UTC ( [id://86670]=perlquestion: print w/replies, xml ) Need Help??

bikeNomad has asked for the wisdom of the Perl Monks concerning the following question: (subroutines)

I'd like my subroutine to use an optional package but only if it exists.

But if I try to do a 'use OptionalPackage;' my program dies if it doesn't exist. How do I deal with this?

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: Defining a subroutine one of two ways depending on whether a package exists
by ariels (Curate) on Jun 08, 2001 at 11:01 UTC
    If you'd like to separate the use Package; command from the test, you can still do it.

    Use the %INC hash (see perlvar). You need to look for a filename, though, not the package name:

    eval { use Compress::Zlib; } # ... much other code, or in some other module... BEGIN { *myCRC = (exists $INC{'Compress/Zlib.pm'}) ? sub { crc32(@_) } : sub { 0 }; }
Re: Defining a subroutine one of two ways depending on whether a package exists
by bikeNomad (Priest) on Jun 07, 2001 at 22:26 UTC
    You can do something like this:

    BEGIN { eval { require Compress::Zlib; import Compress::Zlib 'crc32'; }; *myCRC = $@ ? sub { 0 } # don't have it : sub { crc32(@_) }; }
    This calls Compress::Zlib::crc32 or just returns 0.

    The way this works is:

    The BEGIN block forces this to happen at the very beginning of the program. The eval tries to load the package (in this case Compress::Zlib) and import the symbol 'crc32' into the current package. If this process succeeds, the eval will leave a null string in $@.

    The *myCRC = $@ ? sub { } : sub { } part sets up the name 'myCRC' in the symbol table of the current package to refer to one of two subroutines that are defined anonymously here.

Re: Defining a subroutine one of two ways depending on whether a package exists
by bikeNomad (Priest) on Jun 07, 2001 at 22:56 UTC
    The way this works is:

    The BEGIN block forces this to happen at the very beginning of the program. The eval tries to load the package (in this case Compress::Zlib) and import the symbol 'crc32' into the current package. If this process succeeds, the eval will leave a null string in $@.

    The *myCRC = $@ ? sub { } : sub { } part sets up the name 'myCRC' in the symbol table of the current package to refer to one of two subroutines that are defined anonymously here.

    Originally posted as a Categorized Answer.

Re: Defining a subroutine one of two ways depending on whether a package exists
by bimleshsharma (Beadle) on Nov 16, 2011 at 06:45 UTC

    You can do something like this:
    BEGIN {
    eval {
    require Compress::Zlib;
    import Compress::Zlib 'crc32'; };
    *myCRC = $@ ? sub { 0 }: sub { crc32(@_) };
    }
    }
    Actually "eval" works like error handling and even after wrong in statment inside eval it does not die and thier returned result can be track using $@.

    Originally posted as a Categorized Answer.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://86670]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (4)
As of 2024-03-29 12:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found