Hi,
Background.
From time to time I enjoy tackling Project Euler problems (106 solved to date). Over the years I’ve developed the following routine: I start a new solution in a separate file named, say, Problem_42.pm which begins like this:
package Problem_42; use strict; use warnings; ... main() unless caller; sub main { # local timing code my $solution = solve(); # print solution and time taken } sub solve { ... $return solution; } ... 1;
That way I can run the solution code directly as perl Problem_42.pm and get a nice output message, or I can call the module from a test script which gets only the solution:
# test.pl ... use Test::More; ... # Create %problems and populate with names and solutions keyed to prob +lem numbers ... for my $i (sort { $a <=> $b } keys %problems) { my $module = 'Problem_' . $i; require $module . '.pm'; my $time0 = time(); my $result = ${module}->solve(); my $time1 = time(); printf "%3d (%2d s): ", $i, int($time1 - $time0 + 0.5); is ( $result, $problems{$i}->{solution}, $problems{$i}->{name} . ': answer' ); print ' ' x 12; cmp_ok ( ($time1 - $time0), '<', MAX_SECONDS, $problems{$i}->{name} . ': time' ); } done_testing();
This works fine, except that sometimes when I add a new solution it affects the way the other modules perform.
In one such case I added a solution and found that a subsequent solution had speeded up considerably. I believe this is due to memory allocation: the new solution used heap memory which was still available when the subsequent module was run, and it so happened that the later module was adding to its available memory in increments, so with that memory already available the overhead of repeated allocations was substantially reduced.
But I have been operating on the assumption that by putting each solution into its own namespace (i.e., package), I have isolated it semantically from the other solutions. It now appears that this is not the case. Adding a module with a use bignum pragma causes a subsequent module to perform incorrectly, even though the pragma is in a separate package and the later module has the correct use declarations..
The problem. I’ve reduced the problem to a minimal case as follows: Create 3 files in the same directory:
# 1725_Pragma.pl use strict; use warnings; use First; use Second;
# First.pm package First; use strict; use warnings; #use bignum; print "First\n"; 1;
# Second.pm package Second; use strict; use warnings; use Math::BigFloat; print "Second\n"; my $f = Math::BigFloat->new(2); $f->bsqrt(); print "$f\n"; 1;
With use bignum commented out as shown above, the output is as expected:
16:38 >perl 1725_Pragma.pl First Second 1.41421356237309504880168872420969807857 16:38 >
<Update> And I get the same value for the square root of 2 if I just run perl Second.pm on its own. </Update>
But with use bignum uncommented, the result is simply wrong:
16:38 >perl 1725_Pragma.pl First Second 2 16:40 >
So, my questions are:
In relation to question 3, note that I’ve tried adding no bignum to the end of First.pm or to the beginning of Second.pm, but this had no effect. :-(
Setup.
Thanks,
| Athanasius <°(((>< contra mundum | Iustus alius egestas vitae, eros Piratica, |
In reply to Pragma clash across modules: bignum and Math::BigFloat by Athanasius
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |