# Strange behavior of or condition in loop

**URL:** <https://www.ruby-forum.com/t/strange-behavior-of-or-condition-in-loop/193450>\
**Category:** Ruby\
**Created:** [August 18, 2010, 12:50am UTC](https://www.ruby-forum.com/t/strange-behavior-of-or-condition-in-loop/193450 "2010-08-18T00:50:30Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![AppleII717](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/59ef9b/32.png) [@AppleII717](https://www.ruby-forum.com/u/AppleII717)\
**Post date:** [August 18, 2010, 12:50am UTC](https://www.ruby-forum.com/t/strange-behavior-of-or-condition-in-loop/193450/1 "2010-08-18T00:50:30Z")

</div>

I don’t understand why ruby’s “or” acts differently in a loop.

This is some code I pulled out of a rails model, expanded the  
assignments and simulated in IRB (1.8.7 and 1.9.2rc)

#simple boolean assignments  
#Why does this work

dirty = false  
found = true  
dirty = dirty or found  
puts dirty.to\_s =\> true

#same type of assignments in loop giving meaning to dirty and found  
#But this does not

a = [“score\_method”, “updated\_at”]  
dirty = false  
a.each{|attrib|  
puts dirty.to\_s + " in "  
found = !( /score\_method|weight|critical|minimum\_value/i =~  
attrib ).nil?  
dirty = dirty or found  
puts dirty.to\_s + " out " + found.to\_s  
}  
puts dirty.to\_s =\> false

#another version with parens around or  
#But this does

a = [“score\_method”, “updated\_at”]  
dirty = false  
a.each{|attrib|  
puts dirty.to\_s + " in "  
found = !( /score\_method|weight|critical|minimum\_value/i =~  
attrib ).nil?  
dirty = (dirty or found)  
puts dirty.to\_s + " out " + found.to\_s  
}  
puts dirty.to\_s =\> true

I’ve been doing to additive boolean assignment stuff forever without  
parens. Guess I just don’t understand Ruby.

---

<div class="post-metadata">

**Author:** ![AppleII717](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/59ef9b/32.png) [@AppleII717](https://www.ruby-forum.com/u/AppleII717)\
**Post date:** [August 18, 2010, 1:44am UTC](https://www.ruby-forum.com/t/strange-behavior-of-or-condition-in-loop/193450/2 "2010-08-18T01:44:58Z")

</div>

and/or aren’t the same as &&/||. they have lower operator precedence  
than  
latter.

i recommend reading this article on the usage for both:

> **[Using “and” and “or” in Ruby - avdi.codes](https://avdi.codes/using-and-and-or-in-ruby/)**
>
> UPDATE: For a newer, better take on this topic, check out this post. UPDATE 2: This topic is part of the Graceful.Dev Flawless Ruby course, which is now completely free! If you use Ruby long enough, you will discover the and and or operators. These...

---

<div class="post-metadata">

**Author:** ![AppleII717](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/59ef9b/32.png) [@AppleII717](https://www.ruby-forum.com/u/AppleII717)\
**Post date:** [August 18, 2010, 2:10am UTC](https://www.ruby-forum.com/t/strange-behavior-of-or-condition-in-loop/193450/3 "2010-08-18T02:10:09Z")

</div>

On Wed, Aug 18, 2010 at 12:40 AM, skim [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> and/or aren’t the same as &&/||. they have lower operator precedence than  
> latter.

And to be particular for the OP’s problem “and” and “or” have lower  
precedence than “=” assignment. (And have the same precedence as each  
other.) So  
dirty = dirty or found  
is being parsed as  
(dirty = dirty) or found  
But since “&&” has a higher precedence than “||” which has a higher  
precedence than “=” assignment, if you replaced the “or” in the  
unbracketted  
version by “||” you should now get the results of the bracketted  
version.  
(At least, it worked for me just now.)

skim: Thanks for the link - I mostly use “&&” and “||” (and sometimes  
also  
parentheses just to be sure and to be explicit) but the explanations of  
the  
history will probably make it easier for me to remember the precedence  
of  
“and” and “or” when I see them being used.

---

<div class="post-metadata">

**Author:** ![AppleII717](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/59ef9b/32.png) [@AppleII717](https://www.ruby-forum.com/u/AppleII717)\
**Post date:** [August 18, 2010, 3:09am UTC](https://www.ruby-forum.com/t/strange-behavior-of-or-condition-in-loop/193450/4 "2010-08-18T03:09:16Z")

</div>

On Aug 17, 7:09 pm, Colin B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> is being parsed as  
> (dirty = dirty) or found  
> But since “&&” has a higher precedence than “||” which has a higher  
> precedence than “=” assignment, if you replaced the “or” in the unbracketted  
> version by “||” you should now get the results of the bracketted version.  
> (At least, it worked for me just now.)
> 
> skim: Thanks for the link - I mostly use “&&” and “||” (and sometimes also  
> parentheses just to be sure and to be explicit) but the explanations of the  
> history will probably make it easier for me to remember the precedence of  
> “and” and “or” when I see them being used.

Thanks for the reply, explanation and link. I knew they had different  
precedence, but I never looked them up but figured they’d be next to  
each other. Never crossed my mind that assignment would have a higher  
precedence.

A little disappointed in that I was happy to see “and” and “or”  
because I never liked the symbol operators. Not so much that they are  
bad, but one language uses & and another uses && and “and” just seems  
so much clearer.

I hopefully will remember the next time, but may just use parentheses  
to keep my mind straight.

Steve A.

---

<div class="post-metadata">

**Author:** ![AppleII717](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/59ef9b/32.png) [@AppleII717](https://www.ruby-forum.com/u/AppleII717)\
**Post date:** [August 18, 2010, 6:06am UTC](https://www.ruby-forum.com/t/strange-behavior-of-or-condition-in-loop/193450/5 "2010-08-18T06:06:37Z")

</div>

AppleII717 wrote:

> I don’t understand why ruby’s “or” acts differently in a loop.
> 
> This is some code I pulled out of a rails model, expanded the  
> assignments and simulated in IRB (1.8.7 and 1.9.2rc)
> 
> #simple boolean assignments  
> #Why does this work
> 
> dirty = false  
> found = true  
> dirty = dirty or found  
> puts dirty.to\_s =\> true

A lot of great info in here but I was left with a question:

Why did it work outside the loop (in the example given above) but not  
inside the loop? So I tried the inside the loop code both in irb and  
from a file (using 1.9.1) and I got false, not true. See the irb session  
below. It makes me feel better that it works the same way in both  
instances.

AppleII717, are you sure you got ‘true’ in the code above? Note that  
there is a ‘true’ output, but I think that it is because (dirty = dirty)  
or found returns true, but dirty is false.

irb(main):001:0\> dirty = false  
=\> false  
irb(main):002:0\> found = true  
=\> true  
irb(main):003:0\> dirty = dirty or found  
=\> true  
irb(main):004:0\> dirty  
=\> false  
irb(main):005:0\> dirty.to\_s  
=\> “false”  
irb(main):006:0\>

js

---

<div class="post-metadata">

**Author:** ![AppleII717](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/59ef9b/32.png) [@AppleII717](https://www.ruby-forum.com/u/AppleII717)\
**Post date:** [August 18, 2010, 8:53am UTC](https://www.ruby-forum.com/t/strange-behavior-of-or-condition-in-loop/193450/6 "2010-08-18T08:53:59Z")

</div>

On Wed, Aug 18, 2010 at 6:06 AM, John S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > found = true  
> > instances.  
> > =\> true  
> > irb(main):004:0\> dirty  
> > =\> false  
> > irb(main):005:0\> dirty.to\_s  
> > =\> “false”  
> > irb(main):006:0\>

~$ irb  
irb(main):001:0\> dirty = false  
=\> false  
irb(main):002:0\> found = true  
=\> true  
irb(main):003:0\> dirty = dirty or found  
=\> true  
irb(main):004:0\> dirty  
=\> false

This works as expected in Ruby 1.8.7.

Jesus.

---

<div class="post-metadata">

**Author:** ![AppleII717](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/59ef9b/32.png) [@AppleII717](https://www.ruby-forum.com/u/AppleII717)\
**Post date:** [August 23, 2010, 1:43am UTC](https://www.ruby-forum.com/t/strange-behavior-of-or-condition-in-loop/193450/7 "2010-08-23T01:43:53Z")

</div>

On 8/17/10, AppleII717 [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> dirty = dirty or found
> 
> ```

I recommend you write it this way instead:

dirty ||= found

---

<div class="post-metadata">

**Author:** ![AppleII717](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/59ef9b/32.png) [@AppleII717](https://www.ruby-forum.com/u/AppleII717)\
**Post date:** [August 18, 2010, 5:57pm UTC](https://www.ruby-forum.com/t/strange-behavior-of-or-condition-in-loop/193450/8 "2010-08-18T17:57:22Z")

</div>

John S. wrote:

> Why did it work outside the loop (in the example given above) but not  
> inside the loop? So I tried the inside the loop code both in irb and  
> from a file (using 1.9.1) and I got false, not true. See the irb session  
> below. It makes me feel better that it works the same way in both  
> instances.

Just to clarify: I meant I tried the outside the loop code in irb, not  
the inside the loop code. Sorry, it was late last night.

The output agrees with Jesus’ out put above.

js
