Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Bignum breaks Time::Local?

by cunningrat (Novice)
on Nov 05, 2012 at 22:45 UTC ( #1002396=perlquestion: print w/ replies, xml ) Need Help??
cunningrat has asked for the wisdom of the Perl Monks concerning the following question:

This drove me nuts for several hours today until I figured it out. Sample code below:

#!/usr/bin/perl use strict; use Time::Local; #use bignum(p => -3); my $key='121005'; print $key." ==> ".convtime($key)."\n"; sub convtime { my @months=qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); my @dow=qw{Sun Mon Tue Wed Thu Fri Sat}; my $date=@_[0]; my $year=substr $date,0,2; $year += 100; my $month=substr $date,2,2; $month -= 1; my $day=substr $date,4; my $gmt = timegm(0,0,0,$day,$month,$year); my @gmtime = gmtime($gmt); my $convstring=$dow[$gmtime[6]]." ".$months[$gmtime[4]]." ".$gmtime[3 +]; return $convstring }

If you run this, it returns "121005 ==> Fri Oct 5", as it should. If you uncomment the "use bignum" line, however, it returns "121005 ==> Mon Jan 23".

What I *think* (after some testing) is going on is that the Math::BigInt and Math::Bigfloat overload the arithmetic operators, which breaks timegm().

Is this expected behavior and/or documented anywhere?

Comment on Bignum breaks Time::Local?
Download Code
Re: Bignum breaks Time::Local?
by tobyink (Abbot) on Nov 05, 2012 at 22:54 UTC

    I see the bug you describe in Perl 5.8 and 5.10, but it seems to be fixed in 5.12, 5.14 and 5.16.

    Having checked the changelogs for bignum and Time::Local and also perl5120delta I can't figure out what exactly fixed this.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
      That explains it, Toby. Thanks. (I'm stuck using perl 5.8, unfortunately.)
Re: Bignum breaks Time::Local? (constants)
by tye (Cardinal) on Nov 05, 2012 at 23:34 UTC
    What I *think* (after some testing) is going on is that the Math::BigInt and Math::Bigfloat overload the arithmetic operators, which breaks timegm().

    No, overloading of operators is based only on the arguments given to them. But 'use bignum;' overloads numeric constants. So, for example:

    timegm(0,0,0,$day,$month,$year)

    becomes

    timegm( Math::BigInt->new(0), Math::BigInt->new(0), Math::BigInt->new(0), $day, $month, $year )

    And Math::BigInt might not be careful enough to have Math::BigInt->new(0) act enough like just plain 0 for timegm()'s usage (not surprisingly).

    Is this expected behavior and/or documented anywhere?

    It sounds like you probably read the first sentence of the bignum documentation. Perhaps you failed to go on to read the second sentence.

    This makes bignum.pm a cute demonstration that can be convenient for a one-liner. Otherwise, you should just use Math::BigInt and/or Math::BigFloat directly, so you can avoid making every single time you use a numeric constant magically turn into a complex object that infects the results of any computations that touch it.

    Most of the time you only even need to call Math::BigInt->new() once, so a wrapper like bignum.pm seems of dubious benefit. bignum.pm should probably come with a big warning like "This transforms simple-looking Perl code into something very different and can easily break code".

    - tye        

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1002396]
Approved by Kenosis
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (7)
As of 2014-12-27 19:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (177 votes), past polls