in reply to use/require $MODULE (a variable)

In BEGIN{ require $module; }, you need to replace '::' by '/' since the automatic replacement magic only occurs for barewords. See require for details. For import, the replacement is unwanted, since the package name is its argument.

As for getting things defined before they're needed, you just have to make sure that happens. You'll wind up with a bigger BEGIN block.

The use keyword is unusable for this, it truly doesn't accept a variable as a module name.

After Compline,
Zaxo

Replies are listed 'Best First'.
Re^2: use/require $MODULE (a variable)
by brainbuz (Novice) on Feb 11, 2010 at 07:28 UTC
    I needed to test if a pile of modules were installed on my system, My solution (after reading this and looking elsewhere) was to use backtick and have perl write a series of scripts that would fail if the module wasn't installed.
    #!/usr/bin/perl @modnames = qw / CGI Test::Simple Foo::Bomb Test::More / ; print "Testing for Modules: @modnames\n\n" ; open STDERR, '>/dev/null' ; foreach $module ( @modnames ) { open OTHERSELF, '>REAL.pl' ; print OTHERSELF qq/use $module;\n print "succeeded $module\n" / ; # With SRDERR directed to devnull a value needs # to be returned to STDOUT, the print provides # a value that can be used in determining success. close OTHERSELF ; print "Trying $module\n" ; $result = `perl REAL.pl` ; if ( $result =~ m/succeeded/i ) { print "Successfully Loaded $module \n" } else { print "\n>>>> Failed to Load $module \n\n" } }

      Why don't you simply use eval?

      The friendly version using try-catch alias eval BLOCK needs a litte bit more typing than the quick-and-dirty eval STRING version, because require only converts barewords to filenames, but not variables.

      eval STRING restarts the Perl parser for each tested module. If the module is already loaded, that's more expensive than needed. If not, the Perl parser must be started anyway to load the module.

      #!/usr/bin/perl use strict; use warnings; # "Friendly" version using eval BLOCK foreach my $mod (qw(CGI Test::Simple Foo::Bomb Test::More)) { (my $fn="$mod.pm")=~s|::|/|g; # Foo::Bar::Baz => Foo/Bar/Baz.pm if (eval { require $fn; 1; }) { print "Module $mod loaded ok\n"; } else { print "Could not load $mod. Error Message: $@\n"; } }
      Returns:
      Module CGI loaded ok Module Test::Simple loaded ok Could not load Foo::Bomb. Error Message: Can't locate Foo/Bomb.pm in @ +INC (@INC contains: c:/strawberry/perl/lib c:/strawberry/perl/site/li +b .) at foo.pl line 6. Module Test::More loaded ok
      #!/usr/bin/perl use strict; use warnings; # "Quick-and-dirty" version using eval BLOCK foreach my $mod (qw(CGI Test::Simple Foo::Bomb Test::More)) { if (eval "require $mod; 1;") { print "Module $mod loaded ok\n"; } else { print "Could not load $mod. Error Message: $@\n"; } }
      Returns:
      Module CGI loaded ok Module Test::Simple loaded ok Could not load Foo::Bomb. Error Message: Can't locate Foo/Bomb.pm in @ +INC (@INC contains: c:/strawberry/perl/lib c:/strawberry/perl/site/li +b .) at (eval 5) line 1. Module Test::More loaded ok

      Note that there is a little difference in the error message.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)