diff options
author | Tels <nospam-abuse@bloodgate.com> | 2007-06-16 16:33:47 +0200 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2007-06-17 13:28:00 +0000 |
commit | d1a15766ff5cdfaf84d91442a68bc2a05880bf12 (patch) | |
tree | 050d2d413b2850d26d0aee67b05c542490fad92a /lib/bigrat.pm | |
parent | 3006a4e1991c29fe722177d0ddb5a525c7ce8822 (diff) | |
download | perl-d1a15766ff5cdfaf84d91442a68bc2a05880bf12.tar.gz |
bignum 0.22 take 4 (hex()/oct() overloading)
Message-Id: <200706161433.47489@bloodgate.com>
p4raw-id: //depot/perl@31403
Diffstat (limited to 'lib/bigrat.pm')
-rw-r--r-- | lib/bigrat.pm | 122 |
1 files changed, 99 insertions, 23 deletions
diff --git a/lib/bigrat.pm b/lib/bigrat.pm index 7888aa4481..884e9dab31 100644 --- a/lib/bigrat.pm +++ b/lib/bigrat.pm @@ -3,15 +3,22 @@ use 5.006002; $VERSION = '0.22'; require Exporter; -@ISA = qw( Exporter ); +@ISA = qw( bigint ); @EXPORT_OK = qw( ); @EXPORT = qw( inf NaN ); use strict; use overload; +require bigint; # no "use" to avoid callind import ############################################################################## +BEGIN + { + *inf = \&bigint::inf; + *NaN = \&bigint::NaN; + } + # These are all alike, and thus faked by AUTOLOAD my @faked = qw/round_mode accuracy precision div_scale/; @@ -48,24 +55,6 @@ sub AUTOLOAD Carp::croak ("Can't call bigrat\-\>$name, not a valid method"); } -sub upgrade - { - $Math::BigInt::upgrade; - } - -sub _binary_constant - { - # this takes a binary/hexadecimal/octal constant string and returns it - # as string suitable for new. Basically it converts octal to decimal, and - # passes every thing else unmodified back. - my $string = shift; - - return Math::BigInt->new($string) if $string =~ /^0[bx]/; - - # so it must be an octal constant - Math::BigInt->from_oct($string); - } - sub unimport { $^H{bigrat} = undef; # no longer in effect @@ -79,6 +68,25 @@ sub in_effect $hinthash->{bigrat}; } +############################################################################# +# the following two routines are for Perl 5.9.4 or later and are lexical + +sub _hex + { + return CORE::hex($_[0]) unless in_effect(1); + my $i = $_[0]; + $i = '0x'.$i unless $i =~ /^0x/; + Math::BigInt->new($i); + } + +sub _oct + { + return CORE::oct($_[0]) unless in_effect(1); + my $i = $_[0]; + return Math::BigInt->from_oct($i) if $i =~ /^0[0-7]/; + Math::BigInt->new($i); + } + sub import { my $self = shift; @@ -87,6 +95,13 @@ sub import $^H{bigrat} = 1; # we are in effect + # for newer Perls always override hex() and oct() with a lexical version: + if ($] > 5.009004) + { + no warnings 'redefine'; + *CORE::GLOBAL::oct = \&_oct; + *CORE::GLOBAL::hex = \&_hex; + } # some defaults my $lib = ''; my $lib_kind = 'try'; my $upgrade = 'Math::BigFloat'; @@ -133,6 +148,18 @@ sub import $trace = 1; splice @a, $j, 1; $j --; } + elsif ($_[$i] eq 'hex') + { + splice @a, $j, 1; $j --; + no warnings 'redefine'; + *CORE::GLOBAL::hex = \&bigint::_hex_global; + } + elsif ($_[$i] eq 'oct') + { + splice @a, $j, 1; $j --; + no warnings 'redefine'; + *CORE::GLOBAL::oct = \&bigint::_oct_global; + } else { die ("unknown option $_[$i]"); @@ -184,7 +211,7 @@ sub import } # Take care of octal/hexadecimal constants - overload::constant binary => sub { _binary_constant(shift) }; + overload::constant binary => sub { bigint::_binary_constant(shift) }; # if another big* was already loaded: my ($package) = caller(); @@ -196,9 +223,6 @@ sub import } } -sub inf () { Math::BigInt->binf(); } -sub NaN () { Math::BigInt->bnan(); } - 1; __END__ @@ -219,6 +243,11 @@ bigrat - Transparent BigNumber/BigRational support for Perl print 1/3,"\n"; # 0.33333... } + # Note that this will make hex() and oct() be globally overriden: + use bigrat qw/hex oct/; + print hex("0x1234567890123490"),"\n"; + print oct("01234567890123490"),"\n"; + =head1 DESCRIPTION All operators (including basic math operations) are overloaded. Integer and @@ -406,6 +435,18 @@ line. This means the following does not work: This will be hopefully fixed soon ;) +=item hex + +Override the build-in hex() method with a version that can handle big +integers. Note that under Perl v5.9.4 or ealier, this will be global +and cannot be disabled with "no bigint;". + +=item oct + +Override the build-in oct() method with a version that can handle big +integers. Note that under Perl v5.9.4 or ealier, this will be global +and cannot be disabled with "no bigint;". + =item v or version This prints out the name and version of all modules used and then exits. @@ -414,6 +455,41 @@ This prints out the name and version of all modules used and then exits. =back +=head1 CAVAETS + +=over 2 + +=item in_effect() + +This method only works on Perl v5.9.4 or later. + +=item hex()/oct() + +C<bigint> overrides these routines with versions that can also handle +big integer values. Under Perl prior to version v5.9.4, however, this +will not happen unless you specifically ask for it with the two +import tags "hex" and "oct" - and then it will be global and cannot be +disabled inside a scope with "no bigint": + + use bigint qw/hex oct/; + + print hex("0x1234567890123456"); + { + no bigint; + print hex("0x1234567890123456"); + } + +The second call to hex() will warn about a non-portable constant. + +Compare this to: + + use bigint; + + # will warn only under Perl older than v5.9.4 + print hex("0x1234567890123456"); + +=back + =head1 EXAMPLES perl -Mbigrat -le 'print sqrt(33)' |