I'm not sure how the /SCALARS end up there
Import sub as requested
sub import
{
my $self = shift;
$IMPORT++; # remember we did import()
my @a; my $l = scalar @_;
my $warn_or_die = 0; # 0 - no warn, 1 - warn, 2 - die
for ( my $i = 0; $i < $l ; $i++ )
{
if ($_[$i] eq ':constant')
{
# this causes overlord er load to step in
overload::constant
integer => sub { $self->new(shift) },
binary => sub { $self->new(shift) };
}
elsif ($_[$i] eq 'upgrade')
{
# this causes upgrading
$upgrade = $_[$i+1]; # or undef to disable
$i++;
}
elsif ($_[$i] =~ /^(lib|try|only)\z/)
{
# this causes a different low lib to take care...
$CALC = $_[$i+1] || '';
# lib => 1 (warn on fallback), try => 0 (no warn), only => 2 (di
+e on fallback)
$warn_or_die = 1 if $_[$i] eq 'lib';
$warn_or_die = 2 if $_[$i] eq 'only';
$i++;
}
else
{
push @a, $_[$i];
}
}
# any non :constant stuff is handled by our parent, Exporter
if (@a > 0)
{
require Exporter;
$self->SUPER::import(@a); # need it for subclasses
$self->export_to_level(1,$self,@a); # need it for MBF
}
# try to load core math lib
my @c = split /\s*,\s*/,$CALC;
foreach (@c)
{
$_ =~ tr/a-zA-Z0-9://cd; # limit to sane characters
}
push @c, \'FastCalc', \'Calc' # if all fail, try these
if $warn_or_die < 2; # but not for "only"
$CALC = ''; # signal error
foreach my $l (@c)
{
# fallback libraries are "marked" as \'string', extract string if
+nec.
my $lib = $l; $lib = $$l if ref($l);
next if ($lib || '') eq '';
$lib = 'Math::BigInt::'.$lib if $lib !~ /^Math::BigInt/i;
$lib =~ s/\.pm$//;
if ($] < 5.006)
{
# Perl < 5.6.0 dies with "out of memory!" when eval("") and ':co
+nstant' is
# used in the same script, or eval("") inside import().
my @parts = split /::/, $lib; # Math::BigInt => Math
+ BigInt
my $file = pop @parts; $file .= '.pm'; # BigInt => BigInt.pm
require File::Spec;
$file = File::Spec->catfile (@parts, $file);
eval { require "$file"; $lib->import( @c ); }
}
else
{
eval "use $lib qw/@c/;";
}
if ($@ eq '')
{
my $ok = 1;
# loaded it ok, see if the api_version() is high enough
if ($lib->can('api_version') && $lib->api_version() >= 1.0)
{
$ok = 0;
# api_version matches, check if it really provides anything we nee
+d
for my $method (qw/
one two ten
str num
add mul div sub dec inc
acmp len digit is_one is_zero is_even is_odd
is_two is_ten
zeros new copy check
from_hex from_oct from_bin as_hex as_bin as_oct
rsft lsft xor and or
mod sqrt root fac pow modinv modpow log_int gcd
/)
{
if (!$lib->can("_$method"))
{
if (($WARN{$lib}||0) < 2)
{
require Carp;
Carp::carp ("$lib is missing method '_$method'");
$WARN{$lib} = 1; # still warn about the lib
}
$ok++; last;
}
}
}
if ($ok == 0)
{
$CALC = $lib;
if ($warn_or_die > 0 && ref($l))
{
require Carp;
my $msg = "Math::BigInt: couldn't load specified math lib(s), fa
+llback to $lib";
Carp::carp ($msg) if $warn_or_die == 1;
Carp::croak ($msg) if $warn_or_die == 2;
}
last; # found a usable one, break
}
else
{
if (($WARN{$lib}||0) < 2)
{
my $ver = eval "\$$lib\::VERSION" || 'unknown';
require Carp;
Carp::carp ("Cannot load outdated $lib v$ver, please upgrade");
$WARN{$lib} = 2; # never warn again
}
}
}
}
if ($CALC eq '')
{
require Carp;
if ($warn_or_die == 2)
{
Carp::croak ("Couldn't load specified math lib(s) and fallback d
+isallowed");
}
else
{
Carp::croak ("Couldn't load any math lib(s), not even fallback t
+o Calc.pm");
}
}
# notify callbacks
foreach my $class (keys %CALLBACKS)
{
&{$CALLBACKS{$class}}($CALC);
}
# Fill $CAN with the results of $CALC->can(...) for emulating lower
+math lib
# functions
%CAN = ();
for my $method (qw/ signed_and signed_or signed_xor /)
{
$CAN{$method} = $CALC->can("_$method") ? 1 : 0;
}
# import done
}
sub from_hex
|