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

How can I include a module for Windows only??

by pijush (Scribe)
on Dec 17, 2003 at 14:45 UTC ( #315278=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks!
I have written a perl script which will run both in UNIX and Windows platform. This script will install a software. To install software in UNIX I have used Expect module and for windows I have used Setupsup module. But both modules are specific to one platform.
To include appropriate module according to the OS I have used following code in the top of my perl script.
BEGIN { eval { require Expect; import Expect; require Win32::Setupsup; import Win32::Setupsup; } } use strict; ------- -------
This is working fine for Unix platform and includes Expect and in case of windows it does not include Expect. But for windows it also does not include Win32::Setupsup .
How can I include both modules depending upon OS.
Any help really appreciated.
Thanks in advance.

Replies are listed 'Best First'.
Re: How can I include a module for Windows only??
by broquaint (Abbot) on Dec 17, 2003 at 14:52 UTC
    Just check the $^O variable (see. perlvar for more info) e.g
    BEGIN { if($^O =~ /^Win/) { require Win32::Setupsup; Win32::Setupsup->import; } else { require Expect; Expect->import } }


Re: How can I include a module for Windows only??
by Benedictus (Beadle) on Dec 17, 2003 at 15:55 UTC

    You can use the if module to "use" another module if a condition is true. In your case, you might have:

    use if ($^O =~ /Win/i), "Win32::Setupsup"; use if ($^O !~ /Win/i), "Expect";

    Warning: the above code is untested.

    The "if" module should come with Perl, but you can get it from CPAN if need be.

Re: How can I include a module for Windows only??
by edoc (Chaplain) on Dec 17, 2003 at 15:00 UTC

    ..just a shot in the dark here, but what if you split up the eval into 2?

    BEGIN { eval{ require Expect; import Expect; }; eval{ require Win32::Setupsup; import Win32::Setupsup; } }

    I think when windows fails to require Expect, it's bailing from the eval and not getting to the require Win32 stuff..

    update: hmmm.. ++broquaint



      Hi Monks!
      Thanks a lot.
      I have tried only with two eval blocks and it works fine with me. Thanks ++broquaint.
      Thanks all the monks who have helped me to resolve my problem.
Re: How can I include a module for Windows only??
by davido (Cardinal) on Dec 17, 2003 at 18:18 UTC
    Others have answered the direct question. I liked broquaint's solution best because, instead of trapping an error in an eval, it just makes a decision based on the OS.

    Just one other thought though. It seems that if you continue down this road you're going to have a lot of "if ( $^O =~ /^Win/ ) {...} else {...}" logic scattered throughout the program. It may be advantageous to write a module that handles all this for you. The module would serve as an OS-independant wrapper interface that inherits from the OS-dependant modules you're using. Here's what I was thinking: (Warning, this is untested pseudocode):

    package UniWin; BEGIN { if ( $^O =~ /^MSWin/ ) { require Win32::Setupsup; import Win32::Setupsup; @ISA = qw/Win32::Setupsup/; } else { require Expect; import Expect; @ISA = qw/Expect/; } } # Here you write a OS-generic wrapper around any OS # specific uses of Win32::Setupsup and Expect. # For example, if Setupsup has a "Win_This()" method and # Expect has a "Unix_This()" method, you would write a # wrapper called This() which invokes either method # depending on which OS you're using... 1; package main; use strict; use warnings; use UniWin; # ..........The rest of the program goes here...

    This has the advantage of creating an OS-generic interface to whichever module you ended up loading in an OS-dependant fashion. That will allow the remainder of your code to concentrate on just doing things one way.

    That's just a thought...


      Much like File::Spec. I rather like that approach.
Re: How can I include a module for Windows only??
by ysth (Canon) on Dec 17, 2003 at 20:06 UTC
    The problem with your original code is probably that the require Expect is failing so it never gets to the require Win32::Setupsup. For an easy fix, put the two in separate evals.

    Or you can say:

    use if $^O=~/Win/, "Win32::Setupsup"; use if $^O!~/Win/, "Expect";
    IIRC, is in every perl version > 5.6.1 except 5.8.0, and is also available from cpan.

    Update: I noticed a couple of posts saying /^Win/, which is wrong:

    $ fgrep osname= hints/*.sh */config* hints/'epix2' hints/ The DR2 of MkLinux (osname=linux,archname=ppc-linux) +may need hints/'mpeix' hints/ osname=aix hints/ *) osname='nto' Cross/'linux' NetWare/config.wc:osname='NetWare' Porting/'dec_osf' epoc/'epoc' plan9/config_sh.sample:osname='plan9' win32/config.bc:osname='MSWin32' win32/config.gc:osname='MSWin32' win32/'MSWin32' win32/config.vc64:osname='MSWin32' wince/config.ce:osname='MSWin32'
    It is MSWin32 (even on 64-bit windows, I think).

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://315278]
Approved by DaWolf
Front-paged by DaWolf
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2023-11-30 07:12 GMT
Find Nodes?
    Voting Booth?

    No recent polls found