13

I want avoid iterating over a nil array.

My bad solution:

if nil!=myArr
    myArr.each { |item|
      p item;
    }
 end
james.garriss
  • 12,959
  • 7
  • 83
  • 96
Ben
  • 25,389
  • 34
  • 109
  • 165

6 Answers6

29

For a simple one-liner, you might also use unless myArr.nil?

myArr.each { |item| p item } unless myArr.nil?

Updating for Ruby >= 2.3.0:

If you are comfortable with a nil return rather than avoiding execution entirely, you can use the Safe navigation operator &.. Note though that this differs slightly. Whereas the unless version will skip execution entirely, the &. will execute but return nil.

myArr&.each { |item| p item }
# returns nil
Community
  • 1
  • 1
Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390
15

In ruby, only nil and false are considered as false.

if myArr
    myArr.each { |item|
      p item
    }
end
xdazz
  • 158,678
  • 38
  • 247
  • 274
13

You can wrap the array value in Array().

Array(myArr).each { |item| p item }

As per the documentation, does this:

An array can also be created by using the Array() method, provided by Kernel, which tries to call to_ary, then to_a on its argument.

Basically, this will convert a nil value to []. Which would neither iterate, or throw an error. Fair warning, it will do the same to any value. Array("string") will create ["string"].

Cereal
  • 3,699
  • 2
  • 23
  • 36
3

Simply checking for nil isn't always sufficient. Sometimes a variable you expect to be an array can be initialized as a non-array object when there is only one. It's not common, but proprietary services I've seen might give you a result of nil, "Name1", or ["Name1", "Name2", ...]. To reliably handle this range of input, I prefer to access my arrays like this:

Array.wrap(myArr).each { |item|
  p item
}

Array.wrap will convert nil to [], Object to [Object], and leave existing arrays alone. Also handy for not silently butchering your hashes if one gets passed in instead of an array. (Calling Array(myArr) will convert myArr into an array, which destroys hashes rather than wrapping them in arrays.

GetSet
  • 534
  • 2
  • 6
  • Plain ruby Array will also convert nil to [], Object to [Object], and leave existing arrays alone. You are right about Hashes. – shushugah Feb 09 '19 at 17:10
2

Alternatively, using andand

myArr.andand.each { | item| p item }
markijbema
  • 3,985
  • 20
  • 32
1
myArr ||= []

and then iterate. This will assign empty array to myArr only if it's nil.

Sergey
  • 11,548
  • 24
  • 76
  • 113