Reputation: 23
There's a program that use a regex and somehow I can't manage to understand it.
The code goes +- like this:
@listOfIds = &methodToGetIDs();
foreach my $id (@listOfIds){
if($class =~ /gen/ig){
#does stuff
}
}
What I understand is that if $class
has "gen"
then it will get into the if{}
but sometimes it won't get into it, so I put an else to see what was happening and the code end up like this:
my $class = "genes";
foreach my $id (@listOfIds){
if($class =~ /gen/ig){
print $class."\n"; #to see the value of class
}else{
print "!!!".$class."\n"; #to see the difference if there's any
}#miss this wooops!
}
Guess what? the output was like this:
genes
genes
!!!genes
genes
genes
!!!genes
genes
genes
!!!genes
If the value of $class
doesn't change then why does it gets into the else clause? Guess I don't understand regular expressions at all. Any clues?
Upvotes: 2
Views: 93
Reputation: 496
Because you are using the /g
option. From perlop :
In scalar context, each execution of
m//g
finds the next match, returning true if it matches, and false if there is no further match. The position after the last match can be read or set using thepos()
function; see pos. A failed match normally resets the search position to the beginning of the string, ...
So, you are getting a match the first time you look at the string. Then, the next time you are starting after the position of the first match. I.e. the position is not reset to the start of the string, it continues on where the first match occurs.
The /g
flag is used to indicate you want to match all the times you can in the string. That is useful for counting how many times a substring occurs in the string. In your case, you are testing to see if the pattern matches at all, true, and if it does, do something. You don't need the /g
flag in this case.
my $class = "genes";
foreach my $id (1..6){
if($class =~ /gen/ig){
print $class."\n"; #to see the value of class
}else{
print "!!!".$class."\n"; #to see the difference if there's any
}
}
outputs:
genes
!!!genes
genes
!!!genes
genes
!!!genes
while if you remove the /g
flag you get:
genes
genes
genes
genes
genes
genes
Upvotes: 2
Reputation: 1516
The perlop manpage reads:
In scalar context, each execution of m//g finds the next match, returning true if it matches, and false if there is no further match.
Since if
evaluates the condition in scalar context in your expression, every time it'll first return true, and then false as there are no further matches (I don't understand why it prints twice, and your code doesn't compile).
But note that:
if ( $class =~ /gen/i ) {
will always be true in your example, since $class = "genes"
and doesn't appear to change. Did you mean to check $id
instead?
At any rate, the /g
modifier doesn't seem appropriate for your code.
Upvotes: 0