How can I dynamically include Perl modules without using eval? - perl

I need to dynamically include a Perl module, but if possible would like to stay away from eval due to work coding standards. This works:
$module = "My::module";
eval("use $module;");
But I need a way to do it without eval if possible. All google searches lead to the eval method, but none in any other way.
Is it possible to do it without eval?

Use require to load modules at runtime. It often a good idea to wrap this in a block (not string) eval in case the module can't be loaded.
eval {
require My::Module;
My::Module->import();
1;
} or do {
my $error = $#;
# Module load failed. You could recover, try loading
# an alternate module, die with $error...
# whatever's appropriate
};
The reason for the eval {...} or do {...} syntax and making a copy of $# is because $# is a global variable that can be set by many different things. You want to grab the value as atomically as possible to avoid a race condition where something else has set it to a different value.
If you don't know the name of the module until runtime you'll have to do the translation between module name (My::Module) and file name (My/Module.pm) manually:
my $module = 'My::Module';
eval {
(my $file = $module) =~ s|::|/|g;
require $file . '.pm';
$module->import();
1;
} or do {
my $error = $#;
# ...
};

How about using the core module Module::Load
With your example:
use Module::Load;
my $module = "My::module";
load $module;
"Module::Load - runtime require of both modules and files"
"load eliminates the need to know whether you are trying to require either a file or a module."
If it fails it will die with something of the like "Can't locate xxx in #INC (#INC contains: ...".

Well, there's always require as in
require 'My/Module.pm';
My::Module->import();
Note that you lose whatever effects you may have gotten from the import being called at compile time instead of runtime.
Edit: The tradeoffs between this and the eval way are: eval lets you use the normal module syntax and gives you a more explicit error if the module name is invalid (as opposed to merely not found). OTOH, the eval way is (potentially) more subject to arbitrary code injection.

No, it's not possible to without eval, as require() needs the bareword module name, as described at perldoc -f require. However, it's not an evil use of eval, as it doesn't allow injection of arbitrary code (assuming you have control over the contents of the file you are requireing, of course).
EDIT: Code amended below, but I'm leaving the first version up for completeness.
I use I used to use this little sugar module to do dynamic loads at runtime:
package MyApp::Util::RequireClass;
use strict;
use warnings;
use Exporter 'import'; # gives you Exporter's import() method directly
our #EXPORT_OK = qw(requireClass);
# Usage: requireClass(moduleName);
# does not do imports (wrong scope) -- you should do this after calling me: $class->import(#imports);
sub requireClass
{
my ($class) = #_;
eval "require $class" or do { die "Ack, can't load $class: $#" };
}
1;
PS. I'm staring at this definition (I wrote it quite a while ago) and I'm pondering adding this:
$class->export_to_level(1, undef, #imports);... it should work, but is not tested.
EDIT: version 2 now, much nicer without an eval (thanks ysth): :)
package MyApp::Util::RequireClass;
use strict;
use warnings;
use Exporter 'import'; # gives you Exporter's import() method directly
our #EXPORT_OK = qw(requireClass);
# Usage: requireClass(moduleName);
# does not do imports (wrong scope) -- you should do this after calling me: $class->import(#imports);
sub requireClass
{
my ($class) = #_;
(my $file = $class) =~ s|::|/|g;
$file .= '.pm';
require $file; # will die if there was an error
}
1;

Class::MOP on CPAN has a load_class method for this:
http://metacpan.org/pod/Class::MOP

i like doing things like..
require Win32::Console::ANSI if ( $^O eq "MSWin32" );

Related

"Can't locate object method "new" [...]" in Perl using the AI::Pathfinding::AStar CPAN module

This is the first "serious" thing I'm doing in Perl, so please pardon me if the question is somewhat silly.
I wanted to play around with the A* pathfinding algorithm. I found the AI::Pathfinding::AStar CPAN Module and am basically trying to get the given example to work.
First of all I separated the example into two files, because I couldn't figure out how to make the use My::Map::Package; work with everything in a single file. I came up with the following two files:
MyAstar.pm:
package MyAstar;
use warnings;
use strict;
use base "AI::Pathfinding::AStar";
my %NODES = get_all_nodes();
sub get_all_nodes {...}
sub getSurrounding {...}
main.pl:
#!/usr/bin/env perl
package main;
use lib '/home/foo/astar/';
use warnings;
use strict;
use MyAstar;
my $map = MyAstar->new or die "No map for you!";
my $path = $map->findPath(1, 5);
print join(', ', #$path), "\n";
When I execute main.pl I get the following error:
Can't locate object method "new" via package "MyAstar" at main.pl line 9.
I'm not sure what the problem is here. I would have expected, there to be a subroutine by the name new in the AI::Pathfinding::AStar package, but couldn't find it. Is the CPAN Module broken or am I doing something wrong?
You try to call a function (MyAstar->new, which conventionally is used as a constructor), but you don't define it. There is no default constructor in Perl (like in e.g., Java).
Add something like this to your MyAstar.pm:
sub new {
my $class = shift;
my $self = bless{}, $class;
# initialize $self here as needed, maybe using any passed arguments in #_
return $self;
}

Cannot load `Cwd` (and other, non-core, modules) at runtime

Imagine I want to load a module at runtime. I expected this to work
use warnings;
use strict;
eval {
require Cwd;
Cwd->import;
};
if ($#) { die "Can't load Cwd: $#" }
say "Dir: ", getcwd;
but it doesn't, per Bareword "getcwd" not allowed ....
The Cwd exports getcwd by default. I tried giving the function name(s) to import and I tried with its other functions.
It works with the full name, say Cwd::getcwd, so I'd think that it isn't importing.
This works as attempted for a few other core modules that I tried, for example
use warnings;
use strict;
eval {
require List::Util;
List::Util->import('max');
};
if ($#) { die "Can't load List::Util: $#" }
my $max = max (1, 14, 3, 26, 2);
print "Max is $max\n";
NOTE added Apparently, function calls with parenthesis give a clue to the compiler. However, in my opinion the question remains, please see EDIT at the end. In addition, a function like first BLOCK LIST from the module above does not work.
However, it does not work for a few (well established) non-core modules that I tried. Worse and more confusingly, it does not work even with the fully qualified names.
I can imagine that the symbol (function) used is not known at compile time if require is used at runtime, but it works for (other) core modules. I thought that this was a standard way to load at runtime.
If I need to use full names when loading dynamically then fine, but what is it with the inconsistency? And how do I load (and use) non-core modules at runtime?
I also tried with Module::Load::Conditional and it did not work.
What am I missing, and how does one load modules at runtime? (Tried with 5.16 and 5.10.1.)
EDIT
As noted by Matt Jacob, a call with parenthesis works, getcwd(). However, given perlsub
NAME LIST; # Parentheses optional if predeclared/imported.
this implies that the import didn't work and the question of why remains.
Besides, having to use varied syntax based on how the module is loaded is not good. Also, I cannot get non-core modules to work this way, specially the ones with syntax like List::MoreUtils has.
First, this has nothing to do with core vs. non-core modules. It happens when the parser has to guess whether a particular token is a function call.
eval {
require Cwd;
Cwd->import;
};
if ($#) { die "Can't load Cwd: $#" }
say "Dir: ", getcwd;
At compile time, there is no getcwd in the main:: symbol table. Without any hints to indicate that it's a function (getcwd() or &getcwd), the parser has no way to know, and strict complains.
eval {
require List::Util;
List::Util->import('max');
};
if ($#) { die "Can't load List::Util: $#" }
my $max = max (1, 14, 3, 26, 2);
At compile time, there is no max in the main:: symbol table. However, since you call max with parentheses, the parser can guess that it's a function that will be defined later, so strict doesn't complain.
In both cases, the strict check happens before import is ever called.
List::MoreUtils is special because the functions use prototypes. Prototypes are ignored if the function definition is not visible at compile time. So, not only do you have to give the parser a hint that you're calling a function, you also have to call it differently since the prototype will be ignored:
use strict;
use warnings 'all';
use 5.010;
eval {
require List::MoreUtils;
List::MoreUtils->import('any')
};
die "Can't load List::MoreUtils: $#" if $#;
say 'found' if any( sub { $_ > 5 }, 1..9 );

Prevent strings from being interpreted as a file handle

Perl has the feature that strings named like a file handle are taken to be a filehandle:
# let this be some nice class I wrote
package Input {
sub awesome { ... }
}
So when we do Input->awesome or extra-careful: 'Input'->awesome, the method will get called. Unless:
# now somewhere far, far away, in package main, somebody does this:
open Input, "<&", \*STDIN or die $!; # normally we'd open to a file
This code doesn't even have to be executed, but only be seen by the parser in order to have Perl interpret the string 'Input' as a file handle from now on. Therefore, a method call 'Input'->awesome will die because the object representing the file handle doesn't have awesome methods.
As I am only in control of my class but not of other code, I can't simply decide to only use lexical filehandles everywhere.
Is there any way I can force Input->awesome to always be a method call on the Input package, but never a file handle (at least in scopes controlled by me)? I'd think there shouldn't be any name clash because the Input package is actually the %Input:: stash.
Full code to reproduce the problem (see also this ideone):
use strict;
use warnings;
use feature 'say';
say "This is perl $^V";
package Input {
sub awesome {
say "yay, this works";
}
}
# this works
'Input'->awesome;
# the "open" is parsed, but not actually executed
eval <<'END';
sub red_herring {
open Input, "<&", \*STDIN or die $!;
}
END
say "eval failed: $#" if $#;
# this will die
eval {
'Input'->awesome;
};
say "Caught: $#" if $#;
Example output:
This is perl v5.16.2
yay, this works
Caught: Can't locate object method "awesome" via package "IO::File" at prog.pl line 27.
Using the same identifier for two different things (a used class and filehandle) begs for problems. If your class is used from a different class that's used in the code that uses the filehandle, the error does not appear:
My1.pm
package My1;
use warnings;
use strict;
sub new { bless [], shift }
sub awesome { 'My1'->new }
__PACKAGE__
My2.pm
package My2;
use warnings;
use strict;
use parent 'My1';
sub try {
my $self = shift;
return ('My1'->awesome, $self->awesome);
}
__PACKAGE__
script.pl
#!/usr/bin/perl
use warnings;
use strict;
use My2;
open My1, '<&', *STDIN;
my $o = 'My2'->new;
print $o->awesome, $o->try;
Using the bareword Input as a filehandle is a breach of the naming convention to have only uppercase barewords for FILEHANDLEs and Capitalized/CamelCased barewords for Classes and Packages.
Furthermore lexcial $filehandles have been introduced and encouraged already a very long time ago.
So the programmer using your class is clearly misbehaving, and since namespaces are per definition global this can hardly be addressed by Perl (supporting chorobas statement about begging for problems).
Some naming conventions are crucial for all (dynamic) languages.
Thanks for the interesting question though, the first time I see a Perl question in SO I would preferred to see on perlmonks! :)
UPDATE: The discussion has has been deepened here: http://www.perlmonks.org/?node_id=1083985

module creation using perl script [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do you create a Perl module?
I have the script that reads an xml file and creates hash table. its working properly but now i need to create module for that code, that i can call in my main function.In my main function file path as input and it gives output as hash. now i need to create module for this code.
#!/usr/bin/perl
use warnings;
use strict;
use XML::LibXML::Reader;
#Reading XML with a pull parser
my $file;
open( $file, 'formal.xml');
my $reader = XML::LibXML::Reader->new( IO => $file ) or die ("unable to open file");
my %nums;
while ($reader->nextElement( 'Data' ) ) {
my $des = $reader->readOuterXml();
$reader->nextElement( 'Number' );
my $desnode = $reader->readInnerXml();
$nums{$desnode}= $des;
print( " NUMBER: $desnode\n" );
print( " Datainfo: $des\n" );
}
how can i create module for this code?
You need to create a file with .pm extension, i.e. "MyModule.pm" with this code:
package MyModule;
use warnings;
use strict;
use XML::LibXML::Reader;
sub mi_function_name {
#Reading XML with a pull parser
my $file;
open( $file, 'formal.xml');
my $reader = XML::LibXML::Reader->new( IO => $file ) or die ("unable to open file");
my %nums;
while ($reader->nextElement( 'Data' ) ) {
my $des = $reader->readOuterXml();
$reader->nextElement( 'Number' );
my $desnode = $reader->readInnerXml();
$nums{$desnode}= $des;
print( " NUMBER: $desnode\n" );
print( " Datainfo: $des\n" );
}
}
1; #this is important
And in the file you want to use this module:
use MyModule;
#...
MyModule::mi_function_name;
This is a very simple and basic usage of a module, I recommend the lecture of better tutorials (http://www.perlmonks.org/?node_id=102347) to gain further knowledge on this
Take a look at the Perl Documentation. One of the tutorials included is perlmod. This offers a lot of good information.
First step: Make your program into a subroutine. That way, you can call it your code. I've taken the liberty to do that:
#!/usr/bin/perl
use warnings;
use strict;
use Carp;
use XML::LibXML::Reader;
#Reading XML with a pull parser
sub myFunction {
my $fh = shift; #File Handle (should be opened before calling
my $reader = XML::LibXML::Reader->new( IO => $fh )
or croak ("unable to open file");
my %nums;
while ($reader->nextElement( 'Data' ) ) {
my $des = $reader->readOuterXml();
$reader->nextElement( 'Number' );
my $desnode = $reader->readInnerXml();
$nums{$desnode} = $des;
}
return %nums;
}
1;
I've made a wee change. You notice that I no longer open a file. Instead, you'll pass a file handle to your MyFunction subroutine. Second, instead of printing out $desnode and $des, it now returns a hash that has these values in them. You don't want subroutines to output data. You want them to return the data, and let your program decide what to do with the information.
I've also put in a use Carp; line. Carp gives you two functions (as well as a few others). One is called carp which is a replacement for warning, and the other is called croak which is a replacement for die. What these two functions do is report the line number in the user's program which called your function. That way, the user doesn't see the error in your module, but their program.
I've also added the line 1; at the bottom of your program. When a module loads, if it returns a zero on load, the load fails. Thus, your last statement should return a non-zero value. The 1; guarantees it.
Now that we have a subroutine that you can return, let's make your program into a module.
To create a module, all you have to do is say package <moduleName> on top of your program. And, also make sure that the last statement executes with a non-zero value. The tradition is just to put a 1; as the last line of the program. Modules names end with a .pm suffix by default. Modules names can have components in the names separated by double colons. For example File::Basename. In that case, the module, Basename.pm lives in the directory File somewhere in the #INC list of directories (which, by default includes the current directory).
The package command simply creates a separate namespace, so your package variables and functions don't collide with the names of the variables and functions inside the program that uses your package.
If you use an object oriented interface, there's no reason why you need to export anything. The program that uses your module will simply use the object oriented syntax. If your module is function based, you probably want to export your function names into the main program.
For example, let's take File::Basename. This module imports the function basename and dirname into your program. This allows you to do this:
my $directoryName = dirname $fileName;
Instead of having to do this:
my $direcotryName = File::Basename::dirname $fileName;
To export a function, make sure your module uses the Exporter module, and then set the package variable #EXPORT_OK or #EXPORT to contain the list of functions you're allowing to be exported in the user's program. The difference is that if you say #EXPORT_OK, the functions will be exported, but the user must request each one. If you use #EXPORT, all those functions will automatically be exported.
Using your program as a basis, your module will be called Mypackage.pm and look like this:
#!/usr/bin/perl
package Mymodule;
use warnings;
use strict;
use Exporter qw(import);
use Carp;
use XML::LibXML::Reader;
our #EXPORT_OK(myFunction);
#Reading XML with a pull parser
sub MyFunction {
my $fh = shift; #File Handle (should be opened before calling
my $reader = XML::LibXML::Reader->new( IO => $fh )
or die ("unable to open file");
my %nums;
while ($reader->nextElement( 'Data' ) ) {
my $des = $reader->readOuterXml();
$reader->nextElement( 'Number' );
my $desnode = $reader->readInnerXml();
$nums{$desnode}= $des;
}
return %nums;
}
1;
The big thing is the use of:
package Mypackage
use Exporter qw(import)
our #EXPORT_OK qw(myFunction);
The package function sets up an independent name space, so your variables and function names don't override (or get overwritten) by the user's program.
The use Exporter says that your program is using the import function of the Exporter module. This allows you to import variables and functions into the main namespace of the user's program. That way, the user can simply refer to your function as mi_function_name instead of Mypackage::my_function_name. In theory, you don't have to export anything, and newer modules don't. These module are entirely object oriented or just don't want to bother with namespace issues.
The #EXPORT_OK array says what you're exporting. This is preferred over #EXPORT. With #EXPORT_OK, the developer must specify what functions he wants to import into their program. With #EXPORT, this is done automatically.
In the program that uses your module, you'll need to do this:
use Mypackage qw(myFunction);
Now, all you have to do in your program is
my %returnedHash = myFunction($fh);
Now, things are constantly evolving in Perl, and I've never received any formal training. I simply read the documentation and take a look at various examples and hope that I understand them correctly. So, if someone might say that I'm doing something wrong, they're probably correct. I've also didn't test any of the code. I might have screwed something in your program when I turned it into a subroutine.
However, the gist should be correct: You need to make your code into callable subroutines that return the information you need. Then, you can turn it into a module. It's not all that difficult to do.

How can I use Smart::Comments in a module I load without changing its source?

How can I specify that Smart::Comments be loaded for my original script, as well as for any of the modules it directly loads. However, since it is a source-filter, it would probably wreck havoc if applied to every module loaded by every other loaded module.
For example, my script includes
use Neu::Image;
I would like to load Smart::Comments for Neu::Image as well, but specifying
$ perl -MSmart::Comments script.pl
does not load Smart::Comments for Neu::Image.
This behavior is described in the Smart::Comments documentation:
If you're debugging an application you
can also invoke it with the module
from the command-line:
perl -MSmart::Comments $application.pl
Of course, this only enables smart
comments in the application file
itself, not in any modules that the
application loads.
A few other things that I've looked at already:
Perl Command-Line Options
perldoc perlrun (I searched it
for the word "module")
WORKAROUND
As gbacon mentions, Smart::Comments provides an environment variable option that would allow turning it on or off. However, I would like to be able to turn it on without modifying the original source, if possible.
You almost certainly want to add use Smart::Comments to modules that contain such and then flip the switch in your environment by setting $Smart_Comments appropriately.
Stash-munging, import-hijacking monkey-patching is madness.
But maybe you're into that sort of thing. Say you have Foo.pm:
package Foo;
use Exporter 'import';
our #EXPORT = qw/ foo /;
#use Smart::Comments;
sub foo {
my #result;
for (my $i = 0; $i < 5; $i++) {
### $i
push #result => $i if $i % 2 == 0;
}
wantarray ? #result : \#result;
}
1;
Ordinary usage:
$ perl -MFoo -e 'print foo, "\n"'
024
Ordinary is dull and boring, of course. With run-foo, we take bold, dashing steps!
#! /usr/bin/perl
use warnings;
use strict;
BEGIN {
unshift #INC => \&inject_smart_comments;
my %direct;
open my $fh, "<", $0 or die "$0: open: $!";
while (<$fh>) {
++$direct{$1} if /^\s*use\s+([A-Z][:\w]*)/;
}
close $fh;
sub inject_smart_comments {
my(undef,$path) = #_;
s/[\/\\]/::/g, s/\.pm$// for my $mod = $path;
if ($direct{$mod}) {
open my $fh, "<", $path or die "$0: open $path: $!";
return sub {
return 0 unless defined($_ = <$fh>);
s{^(\s*package\s+[A-Z][:\w]*\s*;\s*)$}
{$1 use Smart::Comments;\n};
return 1;
};
}
}
}
use Foo;
print foo, "\n";
(Please pardon the compactness: I shrunk it so it would all fit in an unscrolled block.)
Output:
$ ./run-foo
### $i: 0
### $i: 1
### $i: 2
### $i: 3
### $i: 4
024
¡Viva!
With #INC hooks we can substitute our own or modified sources. The code watches for attempts to require modules directly used by the program. On a hit, inject_smart_comments returns an iterator that yields one line at a time. When this crafty, artful iterator sees the package declaration, it appends an innocent-looking use Smart::Comments to the chunk, making it appear as though it were in the module's source all along.
By trying to parse Perl code with regular expressions, the code will break if the package declaration isn't on a line by itself, for example. Season to taste.
It doesn't seem like this idea makes any sense. If you are utilizing Smart::Comments in a module, why would you not want to use Smart::Comments in that module's source? Even if you could get Smart::Comments to apply to all modules loaded in a script via -M, it probably wouldn't be a good idea because:
You're obfuscating the fact that your modules are using smart comments by not including the use line in their source.
You could potentially introduce bizarre behavior from modules you use in your script which happen to have what look like smart comments, but aren't really. If a module doesn't contain smart comments, you should not force them down its throat.
As gbacon said, the right way to do this is to use the module in each of your modules that make use of it, and then suppress them with an environment variable when you don't want the output.
Also as he said, it's still probably possible to do this with some "Stash-munging, import-hijacking monkey-patching" madness, but that's a lot of work. I don't think anyone is going to put the effort into giving you a solution along those lines when it is not a good idea in the first place.