13

Am I fundamentally misunderstanding Ruby here? I've been writing Ruby code for about 2 years now and just today stumbled on this...

ruby-1.8.7-p249 > i = true and false
 => false 
ruby-1.8.7-p249 > i
 => true 

Could somebody explain what's going on here please? I'm sure it's to spec, but it just seems counter intuitive to me...

alex
  • 2,036
  • 2
  • 16
  • 19
  • They "why" part is a duplicate of http://stackoverflow.com/questions/1434842/is-there-any-wisdom-behide-and-or-operator-in-ruby , and the what part is a duplicate of http://stackoverflow.com/questions/372652/what-are-the-ruby-gotchas-a-newbie-should-be-warned-about – Andrew Grimm May 10 '10 at 23:28

5 Answers5

30

The operators && and and have different precedence, and = happens to be in between.

irb(main):006:0> i = true and false
=> false
irb(main):007:0> i
=> true
irb(main):008:0> i = true && false
=> false
irb(main):009:0> i
=> false
irb(main):010:0> 

The first is read as (i = true) and false, the second as i = (true && false).

Thomas
  • 174,939
  • 50
  • 355
  • 478
  • thnx! i didn't realize there was a difference between && and and, I'll read up on that. – alex May 10 '10 at 12:24
  • 3
    It's a strange quirk of the Ruby language. I encountered this caveat in a "Ruby for Python programmers" article yesterday, on my first day of learning Ruby :) – Thomas May 10 '10 at 12:26
  • i find it odd i've never encountered this problem before because I use this kind of statements all the time. I have to go back and review a ton of code now :( – alex May 10 '10 at 12:32
  • It's not just Ruby that does this, Perl also has the same oddness with `and` and `&&` having different precedence. – Powerlord May 10 '10 at 13:51
  • Ruby really is too much like Perl in places. There's probably a one-line Perl module so that you can `use Ruby;` and write the rest of your Perl script in Ruby syntax ;) – Thomas May 10 '10 at 15:31
13

and has lower precedence than = so i = true and false is parsed as (i = true) and false.

So the value true is assigned to i and then the return value of that operation (which is true) is anded with false, which causes the whole expression to evaluate to false, even though i still has the value true.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
3

Your line is parsed as

i = true and false
(i = true) and false
true and false

And of course because of i = true, i will be true afterwards.

Marcel Jackwerth
  • 53,948
  • 9
  • 74
  • 88
3

As I understand your code, it is interpreted as :

  • Assign true to i
  • Return i and false

The results seems correct.

Thibault Falise
  • 5,795
  • 2
  • 29
  • 32
1

As others have elucidated above, the keyword and is used when you want to put two different statements on one line. It is just a nicer way of making your code readable.

Thus,

 i = true and false 
implies

i = true; false #(a less widely used code layout in ruby)

or which is the most straightforward way:

  
 i = true
 false 

So, the output is correct. Otherwise, if you were expecting false, then use the boolean and &&.

ceekays
  • 221
  • 3
  • 5
  • This is strictly speaking incorrect; if the first portion of the statement evaluates to false or nil, the second portion never gets evaluated at all. So, for example, `i = false and do_some_stuff` is very different from `i = false; do_some_stuff`, because if in the former, `do_some_stuff` isn't going to run. – philomory Jul 10 '16 at 02:24