views:

133

answers:

5

How does the || works in Perl? I want to achieve c style || operation.

@ARRAY=qw(one two THREE four);

$i=0;

if(($ARRAY[2] ne "three")||($ARRAY[2] ne "THREE"))         #What's the problem with this
{
   print ":::::$ARRAY[2]::::::\n";
}


while(($ARRAY[$i] ne "three")||($ARRAY[$i] ne "THREE"))       #This goes to infinite loop

{

 print "->$ARRAY[$i]\n";
   $i=$i+1;

}
+3  A: 

In ($ARRAY[2] ne "three") || ($ARRAY[2] ne "THREE") the || is a logical or, which means it returns true if at least one of the two expressions is true. Well, it checks the first one and if it is true, it even does not check the second one. And in this case the whole will be true anyway, since $ARRAY[2] cannot be equal to both strings.

Well, it is just like in C I believe. What would you like to achieve?

eumiro
+13  A: 

It works exactly the way you thought it would. However, you have a thinko in your condition. Every value is either not one value or not another value.

I believe you might have wanted

if ($ARRAY[2] ne 'three' && $ARRAY[2] ne 'THREE') { ...

or

if ($ARRAY[2] eq 'three' || $ARRAY[2] eq 'THREE') { ...

You might also want some case-insensitive way of comparing, like

if (lc $ARRAY[2] ne 'three') { ...

or possibly a case-insensitive regexp match.

rafl
thanks @rafi. Some times little mistakes take lot of time to solve.
+2  A: 

while(($ARRAY[$i] ne "three")||($ARRAY[$i] ne "THREE")) :

the expression $ARRAY[$i] ne "three" always evaluates to true. Therefore you have an infinite loop. The || operator has short-circuit behavior so the second expression is never evaluated.

klausbyskov
+1  A: 
 ($ARRAY[$i] ne "three") || ($ARRAY[$i] ne "THREE")) 

This is going to be true in every case. It's either going to be not "three" or not "THREE". You want &&.

syrion
+5  A: 

Two general points. (1) Your Perl scripts should include use strict and use warnings. (2) In most situations, you can iterate directly over an array, avoiding subscripts entirely. An example:

use strict;
use warnings;

my @ARRAY = qw(one two THREE four);

for my $item (@ARRAY){
    last if lc $item eq 'three';
    print $item, "\n";
}
FM
ya @FM I will apply your points in my code.