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

Hey peeps,

lack of caffeine has forced me into turning to my fellow monks instead of banging my head on this for another 4 hours. I'm trying to load a module (from a known namespace) inside a subroutine and pass the parameters of that subroutine to a subroutine of the module I loaded. I tried a plain BEGIN {} block with some eval and require/use in it. I briefly considered Autoload. Something like this illustrates (but not works) the way I want it somehow...
sub routine { my $module = shift; my $routine = shift; my @params = @_; BEGIN { use "Foo::Bar::$module"; } #do something with $@ my $return = &{Foo::Bar::$module::$routine}(@params); return $return; }
Any help would be appreciated :)

Greetz
Beatnik
...Perl is like sex: if you're doing it wrong, there's no fun to it.

Replies are listed 'Best First'.
Re: Loading an unknown module
by broquaint (Abbot) on Jun 27, 2002 at 23:47 UTC
    Firstly the BEGIN block is going to happen at compile-time so it's irrelevant that's it's in the function. If you want to include a module at run-time you could use the tried and tested eval() & use()
    sub routine { my $module = shift; my $routine = shift; my @params = @_; eval qq{ use "Foo::Bar::$module"; }; no strict 'refs'; return &{"Foo::Bar::$module::$routine"}(@params); }
    There's also the very handy autouse module which should do the magic for you
    sub routine { my $module = shift; my $routine = shift; my @params = @_; require autouse; autouse->import( "Foo::Bar::$module", "Foo::Bar::$module::$routine" ); no strict 'refs'; return &{"Foo::Bar::$module::$routine"}(@params); }
    I'm not sure if that's exactly how it should be used so checkout merlyn's Objects of runtime-determined classes for reference.
    HTH

    _________
    broquaint

      I don't think there's any point in using autouse that way, as the main purpose of autouse is to delay loading of the module from compile time to run time and if you call autouse dynamically, that's pretty much the same thing as using a straight eval.

        OMG, someone recommending against modules! <simpsons voice="Chief Wiggum">Get 'em boys</simpsons>. Seriously though the reason for using autouse in this case is the same as any situation in where you can use a module over rolling your own. There's also the fact that autouse != eval 'use Module'. Although it's not necessary I think I'd prefer to use a core module over my own code, but as always TIMTOWTDI.
        HTH

        _________
        broquaint

Re: Loading an unknown module
by Aristotle (Chancellor) on Jun 27, 2002 at 23:03 UTC
    use Module; equates to
    BEGIN { require Module; import Module; }
    What you want to do is to require the module - and no BEGIN block involved.

    Makeshifts last the longest.

      Well yeah, I know... the problem is that I dont know what module I'll be loading (I can narrow down to namespace tho). I need to pass parameters to a subroutine in that module too :)

      Greetz
      Beatnik
      ...Perl is like sex: if you're doing it wrong, there's no fun to it.
        you're looking at Aristotls's post, but you aren't reading his words.

        try reading the perldocs for require, import, and use, and then maybe you'll have a better understanding of what he's saying.

        As a hint: you most definitely, absolutely, do NOT want a BEGIN block if you aren't going to know the full Module untill run time. (a close inspection of the "Package Constructors and Destructors" section of the perldoc perlmod should help you see why)