Strange behavior of or condition in loop

A

AppleII717

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.
 
C

Colin Bartlett

[Note: parts of this message were removed to make it a legal post.]

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.
 
A

AppleII717

[Note:  parts of this message were removed to make it a legal post.]

and/or aren't the same as &&/||.  they have lower operator precedencethan
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.


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 Alex
 
J

John Sikora

AppleII717 said:
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
 
J

Jesús Gabriel y Galán

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 =3D dirty= )
or found returns true, but dirty is false.

irb(main):001:0> dirty =3D false
=3D> false
irb(main):002:0> found =3D true
=3D> true
irb(main):003:0> dirty =3D dirty or found
=3D> true
irb(main):004:0> dirty
=3D> false
irb(main):005:0> dirty.to_s
=3D> "false"
irb(main):006:0>

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

This works as expected in Ruby 1.8.7.

Jesus.
 
J

John Sikora

John said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,146
Messages
2,570,832
Members
47,374
Latest member
anuragag27

Latest Threads

Top