Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

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 { "0.9.9.0"; } }

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/Pack.pm 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?

Comment on Conditionally faking a module
Select or Download Code
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 { "0.9.9.0"; }; } ## 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/Pack.pm 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\Pack.pm 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?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (6)
As of 2015-07-05 15:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (67 votes), past polls