http://qs321.pair.com?node_id=11125117

nysus has asked for the wisdom of the Perl Monks concerning the following question:

Disregard. This was a problem in the return value from get_value(), not the while loop test. Sorry to bother everyone.

Got this simple while loop:

sleep 60; my $status; while(!(($status = get_value()) eq 'initializing')) { sleep 10; }

The $status is set to the value returned by the get_value() function. When the value returned is no longer 'initializing', I want the loop to terminate. However, the while loop never terminates. It keeps going even when get_value() returns 'ok' and I'm not sure why. I've tried a few different iterations of this code to no avail.

This simplified version code works as expected:

use strict; use warnings; my $count = 0; my $status; while (($status = gv() eq 'initializing')) { print 'stuck in loop' . "\n"; } sub gv { $count ++; return 'initializing' if $count < 5; return 'ok'; }

But when I try to duplicated this in my real world code, it doesn't work.

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: While loop does not terminate
by haukex (Archbishop) on Dec 13, 2020 at 17:25 UTC
    This simplified version code works as expected:

    Please mark your updates as such: It is uncool to update a node in a way that renders replies confusing or meaningless.

    But when I try to duplicated this in my real world code, it doesn't work.

    Then one of the lines you deleted when going from your original program to your simplified version were the cause of the problem, and not the code you've posted here. Personally I'd probably start with looking at the return values of get_value() by unrolling the while's condition like so:

    use warnings; use strict; use Data::Dump; my $cnt; sub get_value { $cnt++ < 10 ? 'initializing' : 'ok' } my $status; #while( !( ($status = get_value()) eq 'initializing' ) ) { while (1) { dd $status = get_value(); last if $status eq 'initializing'; print "X" } print "Y\n";

    Update: "Disregard. This was a problem in the return value from get_value(), not the while loop test." - yep ;-)

Re: While loop does not terminate
by Corion (Patriarch) on Dec 13, 2020 at 17:25 UTC

    Instead of logging where you are, consider also logging the values that contribute to the loop condition:

    while (($status = gv() eq 'initializing')) { print "stuck in loop with status [$status], waiting for 'initializin +g'\n"; }

    Maybe it is initialising, or there is whitespace at the end...

Re: While loop does not terminate
by nysus (Parson) on Dec 13, 2020 at 18:31 UTC

    The root cause of the problem was that I moved the get_value() function to another package where it did not have access to a variable it needed to work properly. So it was returning unexpected results.

    The root cause of that problem was no tests to catch the problem.

    $PM = "Perl Monk's";
    $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
    $nysus = $PM . ' ' . $MCF;
    Click here if you love Perl Monks

      > that I moved the get_value() function to another package where it did not have access to a variable it needed to work properly.

      how is this possible to happen silently under strict???

      DB<232> use strict;use warnings; print $XXX lobal symbol "$XXX" requires explicit package name (did you forget to declare "my $XXX"?) at (eval 263) [c:/Perl_524/lib/perl5db.pl:737] line 2.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        Strictures don't bleed through to included packages. Consider:

        # noname.pl: use warnings; use strict; use lib '.'; use noname1; print noname1::get_value(); # noname1.pm: package noname1; sub get_value { return $missingVar // 'Bogus value'; } 1;

        Prints:

        Bogus value
        Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
Re: While loop does not terminate
by haukex (Archbishop) on Dec 13, 2020 at 16:52 UTC

    Sorry, I can't reproduce this; if get_value() returns 'initializing', then the loop terminates immediately.

    use warnings; use strict; my $cnt; sub get_value { $cnt++ < 10 ? 'initializing' : 'ok' } my $status; while( !( ($status = get_value()) eq 'initializing' ) ) { print "X" } print "Y\n";

    Just prints one Y.

    Edit: This was posted before the root node was updated, see my reply here.

Re: While loop does not terminate
by Albannach (Monsignor) on Dec 13, 2020 at 16:49 UTC
    I find I need to watch out for exact comparisons, classic one being numeric when using floating point math. In this case, are you sure of the text? You code uses 'initialising' but your discussion below uses 'initializing'.

    cheers!

    Update: Ignore, must have read it wrong.

    --
    I'd like to be able to assign to an luser