0

Possible Duplicate:
What does ||= (or equals) mean in Ruby?

I am learning Ruby and got confused with following code. I can understand what it does but can't understand how this work exactly.

h = Hash.new
h['key1'] ||= 'value1'
=> "value1"

p h
=> {"key1"=>"value1"}
Community
  • 1
  • 1
charles
  • 15
  • 3
  • 1
    See [this](http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html) article for an exhaustive explanation. – KL-7 Jun 20 '12 at 16:04
  • Thanks all for the comments. Specially to KL-7. The article make my understanding very clear. – charles Jun 20 '12 at 16:20
  • @charles The article that you say made it clear shows that the answer you accepted is incorrect, so why did you accept it? – Andrew Marshall Jun 20 '12 at 17:21
  • Duplicate: [What does `||=` mean in Ruby?](http://StackOverflow.Com/q/995593/), [What does `||=` mean in Ruby?](http://StackOverflow.Com/q/3800957/), [what is `||=` in ruby?](http://StackOverflow.Com/q/3945711/), [Double Pipe Symbols in Ruby Variable Assignment?](http://StackOverflow.Com/q/4500375/), [What does the “`||=`” operand stand for in ruby](http://StackOverflow.Com/q/5124930/), [what does a `||=` mean in Ruby language?](http://StackOverflow.Com/q/5230162/), [Is the ruby operator `||=` intelligent?](http://StackOverflow.Com/q/2989862/), … – Jörg W Mittag Jun 21 '12 at 14:03
  • … [What does `||=` mean?](http://StackOverflow.Com/q/7556902/), [What does “`||=`” do in Ruby 1.9.2?](http://StackOverflow.Com/q/7714803/) ['`||=`' operator in Ruby](http://StackOverflow.Com/q/8506257/), [What does the '`||=`' operator do in ruby?](http://StackOverflow.Com/q/9698946/), and probably many others as well. See also [The definitive list of `||=` (OR Equal) threads and pages](http://Ruby-Forum.Com/topic/151660/). Seriously, when will the broken search function get fixed? Guys, it's been four years now! – Jörg W Mittag Jun 21 '12 at 14:04

3 Answers3

0

Given a Hash:

hash = {}

This expression:

hash[:key] ||= :value

Expands to:

hash[:key] || hash[:key] = :value

Ruby's logical operators short circuit, which means that hash[:key] = :value will only be executed if, and only if, hash[:key] is either false or nil.

If it is anything else, its value alone will be sufficient to determine the result of the logical disjunction, and the rest of the expression will not be evaluated.

This is fundamentally different than:

hash[:key] = hash[:key] || :value

In this case, the []= method will be called either way, and the only difference is which argument it will receive: :value if hash[:key] is either false or nil, or the value of hash[:key] itself otherwise.

Matheus Moreira
  • 17,106
  • 3
  • 68
  • 107
-1

It's an abbreviated assignment pseudooperator. There are eleven of them; the most usual one is:

x += y #expands to x = x+y

||= goes the same way:

x ||= y expands to x = x||y

It works for +, -, , /, %, *, &&, ||, &, |, ^, <<, >>.

steenslag
  • 79,051
  • 16
  • 138
  • 171
  • 1
    This is **wrong**. Please see [What does ||= mean in Ruby?](http://stackoverflow.com/questions/995593/what-does-or-equals-mean-in-ruby) – Andrew Marshall Jun 20 '12 at 16:22
  • 1
    While your reasoning _is_ correct, the conclusion is false, as noted by Andrew Marshall. `x ||= y` actually expands to `x || x = y`. The subtle difference is that _no assignment will take place if `x` is either `false` or `nil`_. – Matheus Moreira Jun 20 '12 at 16:31
  • @Andrew Hmm, I wrote this with page 96 of The Ruby Programming Language (Flanagan and Matsomoto) as reference. The expansion `x=x||y` is mentioned there, in a table. In a block of text it is noted that it behaves slightly different in the case of the lvalue being not false or nil (no assignment). – steenslag Jun 20 '12 at 16:44
  • @steenslag Interesting. There's plenty of discussion as to why it's not that (with code to back it up) mentioned in the other question, as well as a good post on [Ruby Inside](http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html). Ultimately it's not *exactly* equivalent to either `a || a = b` or `a ||= b`. – Andrew Marshall Jun 20 '12 at 16:55
-2

the default value in Hash.new is nil

so h['key1'] ||= 'value1' works as "if key='key1' has no corresponding value yet, let the value be 'value1' "

Jokester
  • 5,501
  • 3
  • 31
  • 39
  • That's not entirely true. `h['key1'] = false; h['key1'] ||= 42; h['key1'] #=> 42`. – Andrew Marshall Jun 20 '12 at 16:03
  • @AndrewMarshall sorry but are something conflicting? – Jokester Jun 20 '12 at 16:41
  • Yes. I assigned a value to `h['key']`, then did an `||=` to it, but it got the value from `||=`. Your answer states that this should only happen "if key1 has no corresponding value yet", but I just showed a case where it does when there is a value already. – Andrew Marshall Jun 20 '12 at 16:43
  • That is possible, but I only meant to explain what happened in the given code. – Jokester Jun 20 '12 at 16:51
  • 1
    Doesn't change the fact that your explanation is incorrect. To further confuse things you say there is a "default value", but then say that `||=` only does something if there is "no corresponding value". Which implies that `||=` is essentially a no-op, which it isn't. – Andrew Marshall Jun 20 '12 at 16:58