Subject: | Undefined subroutine error due to Exporter problem (patch included) |
Crypt::Random needs to use a BEGIN block when exporting it's functions. There is a circular reference between Crypt::Random and Crypt::Random::Generator, and depending on the order the modules are used in, it can lead to an 'Undefined subroutine' error.
The following minimal code snippet demonstrates the problem:
------------
#!/usr/bin/perl
use Crypt::Random;
use Crypt::Random::Generator;
my $gen = new Crypt::Random::Generator Strength => 0;
print $gen->integer(Upper => 100), $/;
------------
This will result in the following error message:
Undefined subroutine &Crypt::Random::Generator::makerandom_itv called at lib/Crypt/Random/Generator.pm line 82.
Here is another test that fails (although I can't figure out what Tk does to make it fail?).
------------
#!/usr/bin/perl
use Tk;
use Crypt::Random;
my $r = Crypt::Random::makerandom ( Size => 512, Strength => 1 );
------------
Which results in the following error:
"makerandom" is not exported by the Crypt::Random module
"makerandom_itv" is not exported by the Crypt::Random module
"makerandom_octet" is not exported by the Crypt::Random module
Can't continue after import errors at /usr/local/share/perl/5.8.2/Crypt/Random/Generator.pm line 12
BEGIN failed--compilation aborted at /usr/local/share/perl/5.8.2/Crypt/Random/Generator.pm line 12.
Compilation failed in require at /usr/local/share/perl/5.8.2/Crypt/Random.pm line 18.
BEGIN failed--compilation aborted at /usr/local/share/perl/5.8.2/Crypt/Random.pm line 18.
Compilation failed in require at test.pl line 3.
BEGIN failed--compilation aborted at test.pl line 3.
The fix is trivial. A BEGIN block needs to be used to handle the exporting of functions in Crypt::Random, and it needs to appear before the 'use Crypt::Random::Generator' call. A patch implementing the fix is attached to this bug report.
- Cees
--- Random.pm.orig 2004-01-21 10:34:15.000000000 -0500
+++ Random.pm 2004-01-21 10:34:49.000000000 -0500
@@ -11,14 +11,17 @@
package Crypt::Random;
require Exporter;
use vars qw($VERSION @EXPORT_OK);
+BEGIN {
+ *import = \&Exporter::import;
+ @EXPORT_OK = qw( makerandom makerandom_itv makerandom_octet );
+}
+
use Math::Pari qw(PARI floor Mod pari2pv pari2num lift);
use Carp;
use Data::Dumper;
use Class::Loader;
use Crypt::Random::Generator;
-*import = \&Exporter::import;
-@EXPORT_OK = qw( makerandom makerandom_itv makerandom_octet );
($VERSION) = do { my @r = (q$Revision: 1.13 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r };