-4

Based on what I have read about the ||= operator in Ruby, I would expect that the following line of code should assign the variable a (an as yet unassigned variable) in the example to 5.

a |= "-----n-".index /n/

Just evaluating "-----n-".index /n/ on its own gives you 5.

However, after executing the above line, a is set to true.

The following sets b to false, whereas I would expect that b should be nil:

b |= "-----n-".index /o/

Can you please explain this to me?

mydoghasworms
  • 18,233
  • 11
  • 61
  • 95
  • `|` is the *bitwise* `OR` operator while `||` is the *logical* `OR` operator. On the other hand, `||=` is not an operator. The parser will see `a ||= b` and treat it as `a = a || b`. You can just focus on `||` or `|`. – oldergod Mar 22 '13 at 05:06
  • 1
    That's his error, yes. But why bitwise OR returns boolean when applied to undefined variable - that's a puzzle! – Sergio Tulentsev Mar 22 '13 at 05:08
  • @SergioTulentsev it is not undefined. The parser set to `nil` all ` var = anything` variables. – oldergod Mar 22 '13 at 05:08
  • @oldergod: I know but the [question still stands](http://stackoverflow.com/q/15563200/125816). – Sergio Tulentsev Mar 22 '13 at 05:15
  • @SergioTulentsev It does if you consider a `nil` valued variable being undefined... – oldergod Mar 22 '13 at 05:24
  • Thanks for pointing that out. I did get a bit mixed up with |= and ||=, but even with ||=, a still ends up wrong. So I am going to revise my answer. – mydoghasworms Mar 22 '13 at 05:48
  • Sorry, didn't see the answers to it, so I reverted back to the original question :-/ – mydoghasworms Mar 22 '13 at 05:50

2 Answers2

2

This happens because a |= expr is desugared to a = a | expr. In the right hand side, a is initially nil.

That expression is equivalent to a = nil | expr, which returns true if the argument is non-nil (see documentation on nil#| for details). You probably meant to write a ||= expr which is desugared to a = a || expr.

kputnam
  • 1,061
  • 7
  • 8
  • Sorry, I made a mistake and got mixed up between |= and ||=. Mmmm, I do see now that it works. – mydoghasworms Mar 22 '13 at 05:50
  • `a ||= expr` **IS NOT THE SAME** as `a = a || expr`. It is sometimes the same as `a || a = expr` but not always. See http://stackoverflow.com/a/2505285/421705 – Holger Just Mar 22 '13 at 08:43
1

||= and |= are different operators. You talk about one, but use another. Pay attention!

a ||= "-----n-".index(/n/) # => 5
b ||= "-----n-".index(/o/) # => nil

c |= "-----n-".index(/n/) # => true
d |= "-----n-".index(/o/) # => false
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367