Looping on "if" statement?

T

T

Greetings,

I have been ask to support some old perl code that's been around and
running for sometime. We upgrade our Linux Redhat OS from 3 to 5.5 and
have bumped into a problem with the following if statement:

# parse stdout to xml when:
#
# using xml mode 2 or xml mode 1 and command succeeds
# we have xml obj
# output contains xml formatted data
#
if (($mode == 2 || ($mode == 1 && !$res)) && ref $xml && grep{ m/
[<>]/ }@out)

I was hoping to make a small testcase but have not been able to
reproduce the problem. What happens is perl just loops on this if
statement forever. Just wondering if anything looks obvious to someone
with great Perl skills than myself. This is three layers down in Perl
modules. We have tried 5.8.8, 5.8.0 and version 5.12 of Perl with the
same result. I believe it's an OS issue, but just can't imagine what?

Thanks for any help in advance.

Tom
 
T

T

Greetings,

Just wanted to place an update in case someone else runs into this
problem. It appears to be a Redhat 5.5 issues with the following bit
of code and XML:

grep{m/[<>]/ } @out

@out contains the XML output from a AccuRev CLI command. Here's what
we found:

grep { m/<>/ } @array
* infinite loop only when run on RH5.5 in the overall context of of
our program
* when run by itself in a test program with the same data, it’s fine,
and also runs fine
* in the context of the perl debugger.

grep m/<>/, @array * works as expected

We've switch to the second, Not sure why RH5.5 has this problem. Hope
this helps someone else.

Thanks for the help
Tom
 
C

ccc31807

Greetings,

I have been ask to support some old perl code that's been around and
running for sometime. We upgrade our Linux Redhat OS from 3 to 5.5 and
have bumped into a problem with the following if statement:

        # parse stdout to xml when:
        #
        # using xml mode 2 or xml mode 1 and command succeeds
        # we have xml obj
        # output contains xml formatted data
        #
        if (($mode == 2 || ($mode == 1 && !$res)) && ref $xml && grep{ m/
[<>]/ }@out)

This may be a quibble, but you don't loop on an if statement, you
recurse. You test for the base case with your conditional. If the
conditional is true, you return the base case. If the conditional is
false, you call the function with some subset of the data.

Example:

sub recurse_through_array
{
my @ar = @_;
if (@ar == 0) { return; } # @ar contains nothing
else
{
my $el = pop(@ar);
do_something($el);
recurse_through_array(@ar); # @ar minus one element
}
}
 
U

Uri Guttman

Greetings,

I have been ask to support some old perl code that's been around and
running for sometime. We upgrade our Linux Redhat OS from 3 to 5.5 and
have bumped into a problem with the following if statement:

        # parse stdout to xml when:
        #
        # using xml mode 2 or xml mode 1 and command succeeds
        # we have xml obj
        # output contains xml formatted data
        #
        if (($mode == 2 || ($mode == 1 && !$res)) && ref $xml && grep{ m/
[<>]/ }@out)

c> This may be a quibble, but you don't loop on an if statement, you
c> recurse. You test for the base case with your conditional. If the
c> conditional is true, you return the base case. If the conditional is
c> false, you call the function with some subset of the data.

you shouldn't be one to use terms like recurse! :)

recursing is a sub concept and has nothing to do with if's. and you can
traverse a tree without recursion (either with looping or dispatching to
dedicated subs for each level).


c> Example:

c> sub recurse_through_array
c> {
c> my @ar = @_;
c> if (@ar == 0) { return; } # @ar contains nothing
c> else
c> {
c> my $el = pop(@ar);
c> do_something($el);
c> recurse_through_array(@ar); # @ar minus one element
c> }
c> }

that is tail recursion and is much simpler with a plain loop. also the
pop would likely want to be a shift so you process the leftmost elements
first.

uri
 
C

ccc31807

recursing is a sub concept and has nothing to do with if's. and you can
traverse a tree without recursion (either with looping or dispatching to
dedicated subs for each level).

Recursion deals with the concept of calling the same function with a
subset of the data, and has everything to do with conditionals. If you
can't test for the base case, how could you stop the recursive call?

My point was that iterative controls, such as while, until, for, and
so on, involve looping. Conditional controls, such as if, unless,
case, and so on, involve recursion.

CC.
 
U

Uri Guttman

c> Recursion deals with the concept of calling the same function with a
c> subset of the data, and has everything to do with conditionals. If you
c> can't test for the base case, how could you stop the recursive call?

please don't lecture me on recursion. the OP's problem had nothing to do
with recursion. and recursion can always be done without sub calls and
in a plain loop. sometimes it is cleaner to properly recurse (depending
on the problem and language). other times it is much better to loop or
fake recursion with a loop (which can ALWAYS be done - recursion is a
neat idea but never required)..

c> My point was that iterative controls, such as while, until, for, and
c> so on, involve looping. Conditional controls, such as if, unless,
c> case, and so on, involve recursion.

that is total bull. what does a single if statement with nothing else
have to do with recursion? boolean tests are used everywhere and are not
related to the thing they control. while is just an if with a goto at
the end/beginning. is that recursing? recursion only involves calling a
sub by itself (or deeper in the call tree). how it resolves to exit is
not an issue. and you could stop recursion with a while as well if you
wanted. it is just a boolean test.

uri
 
S

sln

Greetings,

Just wanted to place an update in case someone else runs into this
problem. It appears to be a Redhat 5.5 issues with the following bit
of code and XML:

grep{m/[<>]/ } @out

@out contains the XML output from a AccuRev CLI command. Here's what
we found:

grep { m/<>/ } @array
* infinite loop only when run on RH5.5 in the overall context of of
our program
* when run by itself in a test program with the same data, it’s fine,
and also runs fine
* in the context of the perl debugger.

grep m/<>/, @array * works as expected

We've switch to the second, Not sure why RH5.5 has this problem. Hope
this helps someone else.

Thanks for the help
Tom

Saw this the other day, been thinking about it.
Does:
grep{m/[<>]/ } @out
sound like the most innacuous bit of common Perl code compiled
with the same standard library calls that should span at least
more than one minor revisions of the same OS? If not, problems at
that level, perl won't run.

Of course perl for [your OS] must be compiled with proper headers
and libs. This includes any modules your application uses, in the
case where the module distribute custom binary.

In the case where you have xml chopped up in a @out array,
that won't cause any problem.

use strict;
use warnings;


my @out = split "\n", <<EXML;<root><root>

<root>
EXML


my ($mode, $res, $xml) = (1, 0, \'xml');

if ( ($mode == 2 || ($mode == 1 && !$res)) &&
ref $xml &&
scalar grep{ /[<>]/ }@out )
{
print "works on windows\n";
}
print "done, found ", (scalar grep{ m/[<>]/ } @out), "\n";

__END__


-sln
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top