Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Infinity loop

by doob (Pilgrim)
on Nov 20, 2005 at 16:23 UTC ( [id://510251]=perlquestion: print w/replies, xml ) Need Help??

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

Hello fellow monks. I am a n00b and I have stumbled upon a very perplexing question. I was hoping that with your ultimate powers of programming, you could help me. Here it goes:

I have this loop:

while ( $_[0]->seq() =~ m/CG/g ) {++$CG;}

It goes on to infinity.

$_[0]->seq() : returns a big string -- a dna sequence

And the rest you probably know what it does. So why can't it just work. A being that is higher than me( my so-called teacher) has suggested it's an "order of operations" problem.

Hope it helps.

How can I solve it without writing other lines of code???

Yours truly,
=d(o_o)b=

Replies are listed 'Best First'.
Re: Infinity loop
by Tanktalus (Canon) on Nov 20, 2005 at 16:31 UTC

    Well, that's because $_[0]->seq() continues to return strings that have "CG" in them. And it probably returns a new string each time, or a copy of a string (which would be new), and then the match tries again.

    What you probably want is:

    my $seq = $_[0]->seq(); while ($seq =~ /CG/) { ++$CG }
    But I'm not sure about that. Are you trying to count the number of CG sequences? Then you want:
    $CG += () = $_[0]->seq() =~ /CG/g;
    I think that "+=()=" may be called the "pimply-goatse-operator". Not sure. Ignore that.

    What is it that this code is really trying to accomplish?

      my $seq = $_[0]->seq(); while ($seq =~ /CG/) { ++$CG } is exactly what I had before my ...mentor...told me to use this other method...so I am still scratching my head in perplexion...he told me to seek the answer to how i can make the new line work without adding new lines of code. Thanks, though =d(o_o)b=
        Well you could avoid the temporary variable by using //g in a LIST context instead. I wouldn't recommend it if the temporary list was likely to be of non-trivial size.
        for ( $_[0]->seq() =~ /CG/g ) { ++$CG }
        If course if the body of your loop is really just ++$CG then all you are doing is counting the number of elements in the list. In that case the "pimply-goatse-operator" mentioned earlier in ths thread is what you want.
        If your string result is so huge that the copy really is a problem, you can temporarily make an alias like this:
        for my $seq ($_[0]->seq()) { # in case you need to reset the first match position # (avoid pos() on huge strings) # $seq =~ /\za/g; $CG++ while $seq =~ /CG/g; }
        update

        Interesting enough, due to the way the perl internals work, this doesn't save you memory compared to

        my $seq = $_[0]->seq();
        during the processing, but the gain is less wasted memory when $seq goes out of scope again (this isn't a memory leak, perl will reuse that memory if the scope is entered again)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://510251]
Approved by Tanktalus
Front-paged by Roy Johnson
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (8)
As of 2024-03-28 12:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found