in reply to Re: while loop acting up, though I'm not sure how
in thread while loop acting up, though I'm not sure how

Thanks for your reply. There's no dd function in my version of Perl, but I used

print "@$_" for @{[[ time => $time], [ expiry => $expiry,], [ and => $and ], [ or => $or, ], [ orr => $orr ] ]};

instead and the output was singularly uninformative. I don't know what you were trying to point out in those results; perhaps you can clarify. (Or maybe dd would have been more informative?)

However, I'll try other things from that debugging-advice page. Thanks for the link.

Replies are listed 'Best First'.
Re^3: while loop acting up, though I'm not sure how
by Anonymous Monk on Nov 17, 2015 at 00:32 UTC

    Data::Dump brings in dd, sorry about that :)

    . I don't know what you were trying to point out in those results; perhaps you can clarify.

    Huh?

    If you want to figure out what is going on, you start by gathering information -- the beginning

    Then you either see your problem (wrong value, wrong condition, wrong assumption...) or look for more/different data or you throw away the whole thing and start over

    I'm not sure where your confusion lies so I can't clarify

    Maybe its as simple as

    while( tenSecondsHasPassed() ){ doStuff(); } sub tenSecondsHasPassed { my $newtime = time; my $diff = $newtime - $lasttime; ... ## if expired "end loop" ## if not ten seconds, sleep to make it ten seconds ## if expired "end loop" ## otherwise continue looping }

      Thank you again. I'm still not sure what was wrong with my original code, but using a subroutine has helped; thus:

      use strict; use warnings; my $expiry = time + 3600; my $time = time; sub sleepy { my $oldtime = pop; my $newtime = time; my $diff = $newtime - $oldtime; sleep 10 - $diff if $diff < 10; return 1; } while ( (sleepy $time) and $time + 300 < $expiry ) { $time = time; warn $time; }

        Hooray :D

        Taking it up a notch here is my thoughts

        #!/usr/bin/perl -- use strict; use warnings; { my $sentinel = expireAfter( 1, 9 ); print "begin ", scalar(gmtime),"\n"; while( $sentinel->() ){ print "loop ", scalar(gmtime),"\n"; } print "end ", scalar(gmtime),"\n"; } { my $sentinel = expireAfter( 1, 5 ); print "begin ", scalar(gmtime),"\n"; while( $sentinel->() ){ print "loop ", scalar(gmtime),"\n"; } print "end ", scalar(gmtime),"\n"; } #~ use constant DEBUG => 1 || !!$ENV{PERL_MYAPP_DEBUG}; use constant DEBUG => 0 || !!$ENV{PERL_MYAPP_DEBUG}; =head2 C<<< checkEveryExpireAfter( $every, $after ) >>> check $every seconds, if it hasn't been $every seconds yet, wait until + it has stop checking $after seconds have elapsed checkExpire( $every, $after ) intervalExpire( $every, $after ) afterExpire( $every, $expire ) everyUntil( $second, $expire ) breatheUntil( $second, $expire ) =cut sub expireAfter { my( $ten, $after ) = @_; my $lasttime = time; my $expire = $lasttime + $after; DEBUG and warn "## eA ## ten($ten)after($after)lasttime($lasttime) +expire($expire)"; return sub { my $newtime = time; my $diff = $newtime - $lasttime; if( $expire < $newtime ){ DEBUG and warn "## eA ## expired ( $expire < $newtime )"; return !!0; } elsif( $diff < $ten ){ DEBUG and warn "## eA ## sleep ( $diff < $ten )"; sleep abs( $diff - $ten ); } $lasttime = time; if( $expire < $lasttime ){ DEBUG and warn "## eA ## expired ( $expire > $lasttime )"; return !!0; } else { DEBUG and warn "## eA ## loop ( $expire > $lasttime )"; return !!1; } }; } sub expireAfterGood { my( $ten, $after ) = @_; my $lasttime = time; my $expire = $lasttime + $after; return sub { my $newtime = time; my $diff = $newtime - $lasttime; if( $expire < $newtime ){ warn "( $expire < $newtime )"; return !!0; } elsif( $diff < $ten ){ warn "expired ( $diff < $ten )"; sleep abs( $diff - $ten ); } $lasttime = time; if( $expire < $lasttime ){ warn "expired ( $expire > $lasttime )"; return !!0; } else { return !!1; } }; } sub expireAfterBuggy { my( $ten, $after ) = @_; my $lasttime = time; my $expire = $lasttime + $after; return sub { my $newtime = time; my $diff = $newtime - $lasttime; if( $expire > $lasttime ){ warn "( $expire > $lasttime )"; return !!0; } elsif( $diff < $ten ){ warn "expired ( $diff < $ten )"; sleep abs( $diff - $ten ); } $lasttime = time; if( $expire > $lasttime ){ warn "expired ( $expire > $lasttime )"; return !!0; } else { return !!1; } }; }

        I started with expireAfterBuggy,

        tweaked it until it did the right thing, and then called it expireAfterGood,

        then improved the diagnostics, added documentation, tried to come up with a better name (this part needs work )

        It is also possible to write it so that this does the right thing  while( nameHere( 'timername', 10, 3600 ) ){ ... } but it could "leak" memory if not used in a loop like that

        Important thing, instead of  while( ( sleepy $time) and $time + 300 < $expiry )

        have  while( oneThing($time, $expiry, 300) )

        oneThing can have a sleepy and whatever else you need to make oneThing easier to understand ;) but since they both share $time and its simple scalar, stick it together under oneName