I've run into an odd issue with DateTime and Memoization (often necessary to
get decent performance for processing 10-20k records with repeat dates). I've
processed a lot of data this way but I recently ran into a few records that
caused an infinite loop, below is some simplified sample code that reproduces
the behavior. It goes away if I don't memoize DT::from_object, but I still
find it odd and thought somebody might be interested in looking into it further
(or documenting the potential for trouble?)
I'm using:
$DateTime::VERSION = '0.2901';
$DateTime::Set::VERSION = '0.25';
$DateTime::Event::Recurrence::VERSION = '0.16';
with ActiveState under Win32.
=cut
use Memoize;
use DateTime::Format::Strptime;
use DateTime::Event::Recurrence;
#DateTime::from_object doesn't Memoize well here.
#Granted, there maybe ought to be a normalizer for the locale parameter?
memoize($_) foreach qw/DateTime::from_object DateTime::new/;
my $strp = new DateTime::Format::Strptime(pattern => '%m/%d/%Y %H:%M');
#Behavior seems to be tied to this data, several records preceeding it are OK
@F{qw(ETYP TYPE DESCRP SDateEDateM T W R F S U STime ETime ROOM)}=
qw(CLSS ACADEMIC 6.27 2/1/2001 2/1/2001 0 0 0 R 0 0 0 900 2300 26-100);
$F{Start} =$strp->parse_datetime("$F{SDate} ".
substr($F{STime}, 0,-2) .':'.
substr($F{STime}, -2, 2));
$F{End} =$strp->parse_datetime("$F{SDate} ".
substr($F{ETime}, 0,-2) .':'.
substr($F{ETime}, -2, 2));
$hours = DateTime::Set->from_recurrence(
start => $F{Start},
before => $F{End},
recurrence => sub {
$_[0]->truncate( to => 'hour' )
->add( hours => 1 )
},
);
$iter = $hours->iterator;
#Possibly related: while debugging I somehow, sometimes, managed to get output
#below, but the # of hours were off? I'd get back the even hours only...
printf "There ought to be %i hours\n", scalar $hours->as_list;
#Infinite loop here:
#_callback_previous: iterator can't find a previous value, got 2001-02-01
# after 2001-02-01 at DateTime/Set.pm line 338.
while ( my $dt = $iter->next ) {
my $hour = $dt->hour() || 24; #0..23,24 hours
if( $hour >= 7 && $hour <= 24 ){
doMath($F{ROOM}, $F{Start}->dow, 1, $hour, 1);
}
};
sub doMath{
print "\$stash{ $_[0] }->{usage}->[ $_[1] ]->[ $_[3] ] += $_[2] * $_[4];\n";
$stash{ $_[0] }->{usage}->[ $_[1] ]->[ $_[3] ] += $_[2] * $_[4];
}
__END__
--
H4sICNoBwDoAA3NpZwA9jbsNwDAIRHumuC4NklvXTOD0KSJEnwU8fHz4Q8M9i3sGzkS7BBrm
OkCTwsycb4S3DloZuMIYeXpLFqw5LaMhXC2ymhreVXNWMw9YGuAYdfmAbwomoPSyFJuFn2x8
Opr8bBBidcc=
--
MOTD on Pungenday, the 65th of Discord, in the YOLD 3172:
I've lost all sensation in my shirt