Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Conditionally faking a module

by wanna_code_perl (Pilgrim)
on Jan 13, 2010 at 18:23 UTC ( #817249=perlquestion: print w/replies, xml ) Need Help??
wanna_code_perl has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks,

I've built an application which is designed to run both normally on Linux, or packaged up on Win32 with Cava Packer. Cava Packer comes with Cava::Pack, which I need to fake out, because as far as I can tell, there is no equivalent module for Linux.

I've worked around this with the following code:

BEGIN { package Cava::Pack; sub Resource { $Cava::Pack::dir.'/'.$_[0]; } sub SetResourcePath { $Cava::Pack::dir = $_[0]; } sub GetInfoProductVersion { ""; } }

This works fine in Linux, but in Windows I need to use the real Cava::Pack, and if I add a use Cava::Pack; line, I get function redefinition warnings (not to mention compilation fails on Linux because there is no Cava/ in my @INC.

What I need to do is conditionally use the real Cava::Pack if it is available, or run my above code if it is not available. How do I go about that?

Replies are listed 'Best First'.
Re: Conditionally faking a module
by Anonymous Monk on Jan 13, 2010 at 18:38 UTC
    see use, require, eval
    BEGIN { if( eval { require Cava::Pack; 1 } ) { import Cava::Pack; } else { no strict 'refs'; *Cava::Pack::Resource = sub { $Cava::Pack::dir . '/' . $_[0]; }; *Cava::Pack::SetResourcePath = sub { $Cava::Pack::dir = $_[0]; }; *Cava::Pack::GetInfoProductVersion = sub { ""; }; } ## end unless ( eval { require Cava::Pack...}) } ## end BEGIN
      This was the ticket. Thanks!
Re: Conditionally faking a module
by bobf (Monsignor) on Jan 13, 2010 at 18:40 UTC

      Unfortunately, your example doesn't work:

      eval "use Cava::Pack" or do { die "Using faked out Cava::Pack\n"; }

      I see the "Using faked out Cava::Pack" message on both Linux and Win32 (where Cava::Pack is indeed available).

        That is the reason for a true value, 1
        eval "use Cava::Pack; 1" or die "Oh noes! $@"; eval "use HOW::Cava::Pack; 1" or die "HOW!?! $@"; __END__ HOW!?! Can't locate HOW/Cava/ in @INC (@INC contains: C:/perl/5 +.10.1/lib/MSWin32-x86-multi-thread C:/perl/5.10.1/lib C:/perl/site/5. +10.1/lib/MSWin32-x86-multi-thread C:/perl/site/5.10.1/lib .) at (eval + 2) line 1. BEGIN failed--compilation aborted at (eval 2) line 1.
        Hmm, I don't recall installing Cava::Pack :)

        The code being executed by eval ("") returns nothing (()), which is indistinguishable from the value eval returns on failure.

        You need

        eval "use Cava::Pack; 1"
Re: Conditionally faking a module
by NiJo (Friar) on Jan 13, 2010 at 18:59 UTC
    # add Cava\ at the end of include path, # real Cava::Pack is found earlier push @INC, './dummy' use Cava::Pack
      use happens at BEGIN time, so to make your strategy work you would need
      BEGIN { push @INC, './dummy'; }
      Its shorter to use lib
      use lib './dummy';
        You are right with the BEGIN block, but 'use lib' adds to the high priority end of @INC, so the real package is never found.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://817249]
Approved by NiJo
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2017-01-20 06:40 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (173 votes). Check out past polls.