Home > other >  Does Ruby evaluate both expressions for an OR / || while using it for loop control?
Does Ruby evaluate both expressions for an OR / || while using it for loop control?

Time:10-06

So I know that for an OR or || evaluation such as A || B, Ruby will return true if A is true and does not proceed to evaluate B.

Hence, this code works without error:

i = 1
puts "this returns true" if (i < 5) or ( i.upcase == i)

But when used as a loop control condition, why does Ruby seem to evaluate both expressions? This code will throw an error undefined methodupcase' for 5:Integer (NoMethodError)`

i = 0

while (i < 5) or ( i.upcase == i)
  i =1 
end

CodePudding user response:

If you output the value in each iteration, you will understand the reason.

i = 0

while (i < 5) or (i.upcase == i)
  puts i
  i  = 1 
end

Output:

0
1
2
3
4
Traceback (most recent call last):
        1: from (irb):3
NoMethodError (undefined method `upcase' for 5:Integer)
Did you mean?  case

The error is for a value that is equal to 5. If you change the value of i in the first scenario, even that throws an exception by evaluating the latter condition.

i = 5
puts "this returns true" if (i < 5) or (i.upcase == i)

Output:

Traceback (most recent call last):
        1: from (irb):2
NoMethodError (undefined method `upcase' for 5:Integer)
Did you mean?  case

Reason: As it is the case of A or B. If condition A return false, then it proceeds to check for condition B.

CodePudding user response:

In first case,

    i = 1
    puts "this returns true" if (i < 5) or ( i.upcase == i)

The usage of upcase is for string data type but i is an integer. If you run the code above you receive output this returns true, because the first condition is true and second condition is false. So, since first condition is true, computer has chosen to go with the true condition and hence, the resultant output. It has essentially masked the wrong usage error of upcase. If you exchange the two expressions i.e

    i = 1
    puts "this returns true" if ( i.upcase == i)  or (i < 5)

This will throw error - undefined method upcase for Integer

But if code changes to - for instance,

    i = 1
    puts "this returns true" if ( i == 0)  or (i < 5)

This will output this returns true. The first expression is false but the second expression is true. So, 'or' checks both the conditions. If any one condition is true, the output is true.

Second case:

i = 0

while (i < 5) or ( i.upcase == i)
  i =1 
end

As explained above the wrong usage of upcase for an integer will throw error - undefined method 'upcase' for 5:Integer (NoMethodError) as mentioned.

  •  Tags:  
  • ruby
  • Related