Rewrite bignum’s hex and oct overrides
authorFather Chrysostomos <sprout@cpan.org>
Thu, 4 Oct 2012 07:35:05 +0000 (00:35 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 4 Oct 2012 16:37:58 +0000 (09:37 -0700)
commit9663a7f582d8b5a489da7d8d8800291ca31c05a1
tree07eaba3c2416a2c2a6e46b05825c1e089b3b3cb8
parent40f316a72b14619d13e83acddaab24c95cb0c03c
Rewrite bignum’s hex and oct overrides

As mentioned in <https://rt.cpan.org/Ticket/Display.html?id=79915>,
bigint.pm does not use any prototype when globally overriding hex.
This means that map { hex } ... will stop working in completely unre-
lated code if bigint happens to be loaded.  (Explicit $_ will con-
tinue to work.)

I thought it would be a simple matter of adding the right prototype
depending on perl version (and inferring $_), but the basic tests
I added failed for other reasons after I fixed the prototype and
$_ handling.

It turns out this whole thing is a mess, so I have basically reimple-
mented these two overrides.

What bigint, bignum and bigrat were doing was this: In import,
*CORE::GLOBAL::hex and ::oct are assigned functions that create
Math::BigInt objects if the pragma is in effect.  If import is passed
'hex' or 'oct', then the function assigned does not check the pragma
hints, but simply creates Math::BigInt objects regardless.

This means that ‘use bigrat’ stops hex() and oct() from creating
objects in ‘use bigint’ scopes, and vice versa.  In fact, whichever
pragma is loaded last wins.  Any scopes elsewhere in the program that
use the same pragma will have special hex() and oct() behaviour.  But
the other two lowercase big* pragmata will be disabled with regard to
hex and oct.

Having ‘use bigint 'hex'’ override hex globally makes no sense to me.
I have no qualms about changing it, as it was already broken.  Any
subsequent ‘use bigint;’ would turn off the global override.  So now
it exports hex or oct to the calling package, just like a normal mod-
ule.  You can now also call bigint::hex.

Also, in writing tests I found that oct("20") gives me 20.  Apparently
this was never tested properly.

I also found notes about ‘5.9.4 or later’ when the code checked
$] > 5.009004.  (Actually, in one place the code checked > 5.009003,
so I made it match, as we use the _ prototype now, which was intro-
duced in 5.9.5.)  One was in the docs, so I changed it to 5.10.0,
since  it is not helpful to mention dev versions.  The docs were also
wrong to imply that ‘no bigint’ would countermand ‘use bigint 'hex'’.
MANIFEST
dist/bignum/lib/bigint.pm
dist/bignum/lib/bignum.pm
dist/bignum/lib/bigrat.pm
dist/bignum/t/overrides.t [new file with mode: 0644]