-2

I have the following code:

via = reminders_array[i]['value']['bot-input-keyword'] unless reminders_array[i]['value']['via'].nil?

and

collection = json_element['COLLECTION']['$'] unless json_element['COLLECTION'].nil?

When I search for examples, I saw people use ||= but I can't quite understand its use, especially in the second case.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Satchel
  • 16,414
  • 23
  • 106
  • 192
  • [Concerning `||=`](http://stackoverflow.com/questions/995593/what-does-or-equals-mean-in-ruby) – art-solopov Jun 23 '15 at 17:05
  • `collection = json_element['COLLECTION']['$'] unless json_element['COLLECTION'].nil?` this could also be written as `collection = json_element['COLLECTION']['$'] if json_element['COLLECTION']` but I would need more context to truly understand the problem here – engineersmnky Jun 23 '15 at 17:06

1 Answers1

1

Consider the the following statements:

e #=> NameError: undefined local variable or method `e'...

if false
  e = 7
end
e #=> nil 

f #=> NameError: undefined local variable or method `f'
f = 7 if false
f #=> nil 

As you see, Ruby raises an exception if the value of a local variable (e or f) is sought, but if the variable first appears in a statement, but is not assigned a value, Ruby sets its value to nil. We see that:

a = b unless c.nil?

is the same as:

a = b if c

which is the same as:

a = (c ? b : nil)

which is the same as:

a = c && b

To see why the last expression is equivalent to the preceding two, let's try a couple of examples, both with:

b = 4

c = 2
c && b #=> (2 && 4) => 4

c = nil
c && b #=> (nil && 4) => nil

So I believe you want:

via = reminders_array[i]['value']['via'] &&
  reminders_array[i]['value']['bot-input-keyword']

You asked about ||=, which is a form of abbreviated assignment. When Ruby's sees a ||= b she makes the assignment a = b if a is nil or false:

a || a = b

Two more examples, with b still equal to 4:

a = 2
a ||= 4 #=> a || a = 4 => a => 2 || a = 4) => 2

a = nil
a ||= 4 #=> a || a = 4 => a => nil || a = 4 #=> 4

So if a is nil, a remains nil; else a is set to b.

A common use of ||= is:

a = nil
(a ||= []) << 4
  #=> [4]

a = [4]
(a ||= []) << 6
  #=> [4,6]

In the first instance, a is nil, so a ||= [] converts a to an empty array, to which it appends 4. In the second case, a ([4]) is not nil, so a ||= [] leaves a unchanged ([4]). 6 is then appended to a, making a [4,6].

In addition to ||= there are:

a &&= b #=> a && a = b
a += b  #=> a = a + b
a *= b  #=> a = a * b     

and others (see the doc). A word about a && b. If a is nil, a && b is nil. If a is not nil, a && b is b. Notice that for operators op other than || and &&, a op= b is expanded to a = a op b.

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100