Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Infinite regex loop...

by limzz (Novice)
on Jun 29, 2011 at 19:47 UTC ( #912023=perlquestion: print w/ replies, xml ) Need Help??
limzz has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, The following code is a snippet from a script I'm writing. It seems like the regex is caught in an infinite loop or something. I can't even think clearly right now, so maybe it's something simple, but I cannot for the life of me figure out what the hell is going on. Thanks in advance.

while (<FILE>){ chomp; if ($_ =~ /SPECint_base/){ $SIRtrue = 1; $SFRtrue = 0; } if ($_ =~ /SPECfp_base/){ $SIRtrue = 0; $SFRtrue = 1; } if ($SIRtrue && !($_ =~ /SPECint_base/)){ $SIR{$_}=$_; } if ($SFRtrue && !($_ =~ /SPECfp_base/)){ $SFR{$_}=$_; } }

Clarification: This is supposed to find SPECint_base or SPECfp_base, NOT put them in %SIR or %SFR, then put every line from FILE into a hash until the respective 'true' is false. Second clarification: Maybe it's not an infinite loop, but the script is getting stuck. I've tried putting print statements to debug and it seems to be stuck on the first regex.

Comment on Infinite regex loop...
Download Code
Re: Infinite regex loop...
by philipbailey (Chaplain) on Jun 29, 2011 at 20:00 UTC

    Because $SIRtrue is true whenever /SPECint_base/ matches, this line:

    if ($SIRtrue && !($_ =~ /SPECint_base/)){

    is equivalent to:

    if ($SIRtrue && !$SIRtrue){

    That "if" statement can never be true. A similar argument applies to the final "if" statement. No assignment will ever be made to the %SIR or %SFR hashes.

    You might also wish to note that regex matches in Perl are performed by default on the $_ variable. See perlretut. So you can replace:

    if ($_ =~ /SPECint_base/){

    with this:

    if (/SPECint_base/){

    Update: of course limzz's reply is correct. But we still have not heard from the OP exactly what the behaviour of the program is. There is nothing in the code shown to cause an infinite loop.

      Nope, maybe I should have explained what the code does. Think of SPECint_base and SPECfp_base as headers, then any elements beneath them will be put into the hash, but not the headers themselves.

      Your code, for the most part, seems to do what you want. I don't see how you can end up in a loop. The only portion that seems very suspect is this:

      if ($SIRtrue && !($_ =~ /SPECint_base/)){ $SIR{$_}=$_; } if ($SFRtrue && !($_ =~ /SPECfp_base/)){ $SFR{$_}=$_; }

      You're stuffing the line you find into a hash key named the same as the line value. This is likely not what you want.

      This may be closer to what you want (assuming my data below somewhat resembles your file), but it's honestly hard to say:

      use strict; use warnings; use Data::Dumper; my $str = <<END; SPECint_base 1 2 3 SPECfp_base 4 5 6 END open my $fh, '<', \$str or die "Could not open for read:$!\n"; my $SIRtrue; my $SFRtrue; my %SIR = (); my %SFR = (); while (<$fh>){ chomp; if (/SPECint_base/){ $SIRtrue = 1; $SFRtrue = 0; next; } elsif (/SPECfp_base/){ $SIRtrue = 0; $SFRtrue = 1; next; } if ($SIRtrue)){ push( @{$SIR{SPECint_base}}, $_ ); } elsif ($SFRtrue){ push( @{$SFR{SPECfp_base}}, $_ ); } } print Dumper(\%SIR); print Dumper(\%SFR);

      Output:

      $VAR1 = { 'SPECint_base' => [ '1', '2', '3' ] }; $VAR1 = { 'SPECfp_base' => [ '4', '5', '6' ] };
Re: Infinite regex loop...
by wind (Priest) on Jun 29, 2011 at 20:47 UTC

    What exactly are you trying to accomplish?

    Your code is probably not doing what you want it to do, but there is no looping of any kind except for the file processing. Once that's done your code would finish.

    How exactly are you trying to process the file? I could point out probable flaws in your current code, but it would be more effective if you explained your goal before we start trying to decipher your intent.

      The file is a list. SPECint_base and SPECfp_base are headers. When it finds one or the other, its respective valid variable becomes true. It should not store the header in its respective hash. When it loops through, unless $_ is one of the headers, it should be put in whichever hash.

        I might understand what you want, but try making an example. Show us a fake data file in the format that your using and then state what should be the resultant data structures after processing.

        I know what I mean. Why don't you?

Re: Infinite regex loop...
by graff (Chancellor) on Jun 30, 2011 at 04:21 UTC
    The following code is a snippet from a script I'm writing.

    When you present us with just a snippet (which we are not able to test ourselves), you run the risk of leaving out relevant details, and it would be more effective to show us a fully self-contained and runnable script (with suitable sample data) to demonstrate the problem. (Usually, in the process of trying to distill the problem into a stand-alone demonstration, you will figure out what the problem is and how to fix it on your own. It generally improves your ability to diagnose problems.)

    In the present case, we don't know if maybe you set $/ to undef, and maybe the input file is really big -- in which case, it's probably not the regex that's stalling, but the attempt to read the entire file into a single scalar variable.

    Apart from that (or something like that), I don't see anything to indicate a problem with the code as posted, except that there are "cosmetic" issues that could be improved (and cosmetic improvements can be worthwhile) -- e.g.:

    use strict; open( FILE, '<', "whatever.filename' ) or die "whatever... $!\n"; my $container; my ( %SIR, %SFR ); while (<FILE>){ chomp; if ( /SPECint_base/ ) { $container = \%SIR; } elsif ( /SPECfp_base/ ) { $container = \%SFR ; } elsif ( $container ) { $container->{$_} = undef; # no need to repeat hash key as has +h value } }
    As for trying to debug the process, try running it with 'perl -d' (that is, use the perl debugger), so you can step through it and see where it really gets stuck, and even inspect variables to see whether other parts of the script are doing what you intended.

    (Oh, by the way, are you sure that everything following one or the other "header" string should be included in the corresponding container?)

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (8)
As of 2014-12-21 10:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

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





    Results (104 votes), past polls