Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

dynamic loading modules

by sdetweil (Sexton)
on Sep 03, 2012 at 14:23 UTC ( #991441=perlquestion: print w/replies, xml ) Need Help??
sdetweil has asked for the wisdom of the Perl Monks concerning the following question:

I have this app that is cross platform, supports window, linux, solaris, aix,hpux, linux-z, .. 32 and 64 bit. as I port around, I keep running into some windows only modules not available on other platforms.. duh..

so, I'd like to convert my 'use Win32' to 'require Win32'. and load the library.. seems simple.. but I guess I must be missing the last little thing..

current code

$my osname = Win32::GetOSName();
(note the lack of an explicit 'use')
using examples on the web I changed it to
my modname='Win32'; require $mymodname; import $mymodname qw(GetOSName); $my osname = GetOSName();

which fails
Undefined subroutine &main::GetOSName
all the examples seem to be fine, but they don't show the code that consumes the functions of the package when used in a dynamic load implementation. thanks Sam

Replies are listed 'Best First'.
Re: dynamic loading modules
by daxim (Chaplain) on Sep 03, 2012 at 14:37 UTC
    The symbol GetOSName is not defined at compile time, so move the conditional module loading into a BEGIN block.
      thx.. I added this to my begin block
      if ($^O eq "MSWin32") { print ("begin\n"); my $win32 =""; require $win32; import $win32 qw(GetOSName); }
      I get the print message fom my begin block code. and still call it
      my $os = GetOSName();
      and it still fails
      Undefined subroutine &main::GetOSName

        This is never going to work:

        my $win32 =""; import $win32 qw(GetOSName);

        If there isn't already an import() in your current package, this will effectively become:

        ''->import( 'GetOSName' );

        Because there's no package called, nothing will get imported. You're better off writing:

        Win32->import( 'GetOSName' );

        ... or even:

        'Win32'->import( 'GetOSName' );
        The line calling GetOSName() should never be called on any system other than Windows. Fix the logic of your program.
        لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: dynamic loading modules
by choroba (Bishop) on Sep 03, 2012 at 14:42 UTC
    See if:
    use if 'MSWin32' eq $^O, Win32; if ('MSWin32' eq $^O) { my $osname = MSWin::GetOSName(); }
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      I am already inside an If on the Os 'MSWin32', and do NOT have any 'use Win32' coded anywhere in my application.

      the code works fine, and requires these missing win32 modules when compiled on the unix platforms.

      I don't know what makes it work as is

        use if is not an if. It moves the decision whether to use the module or not into the compilation phase (as BEGIN does).
        لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: dynamic loading modules
by BrowserUk (Pope) on Sep 03, 2012 at 15:55 UTC

    How about this?

    >perl -MWin32 -wE"if(exists $::{'Win32::'} and exists $Win32::{'GetOSN +ame'} ) { say &{'Win32::GetOSName'}; }" WinVistaService Pack 1 >perl -wE"if(exists $::{'Win32::'} and exists $Win32::{'GetOSName'} ) +{ say &{'Win32::GetOSName'}; }" >

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    RIP Neil Armstrong

Re: dynamic loading modules
by bulk88 (Priest) on Sep 03, 2012 at 21:02 UTC
Re: dynamic loading modules
by nikosv (Chaplain) on Sep 03, 2012 at 15:23 UTC
      thanks.. I'll go look at this, but.. this is not the problem..

      dynamically loading the module is my issue.

      this module will not install on an *ix based platform as it is windows only.. I have a workaround, but its manual, and someone else following after me will be stuck with my manual mode.

        I see.what you are after can't happen.You can only save the user the trouble of trying to install your module in an incompatible OS by using Devel-CheckOS
Re: dynamic loading modules
by fishmonger (Chaplain) on Sep 03, 2012 at 15:36 UTC
      sorry, thats again off the mark..

      how do I code the source statement calling the function in the module AFTER I change from hard coded to dynamic loading?

      this part seems to be missing in any text I read..

      my app today uses

      my $os = Win32::GetOSName();

      there is NOT a 'use win32' anywhere.. I know, I coded it all. I don't know if there is some OTHER method loading this module.


      coding explicitly Win32::GetOSName() gets me into trouble, so I ASSUME I have to change the code.. to WHAT?

      just my $os=GetOSName() fails. how is the compiler supposed to set this up for dynamic resolution vs static? thats what I'm asking for.

        Unless I'm misunderstanding your goal, I don't see any reason why you can't use Module::Load or Module::Load::Conditional or a combination of both. Here's a simple test script which works for me.
        #!/usr/bin/perl use strict; use warnings; use Module::Load; my $os = 'Yet Unknown'; if ( $^O =~ /MSWin/ ) { load 'Win32'; $os = Win32::GetOSName(); } print $os;
        Output of my test: D:\perl>

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2018-06-20 00:50 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (116 votes). Check out past polls.