13

I want avoid iterating over a nil array.

My bad solution:

if nil!=myArr
    myArr.each { |item|
      p item;
    }
 end

6 Answers 6

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
Sign up to request clarification or add additional context in comments.

2 Comments

Using nil? is almost always extraneous unless you are specifically testing a value that could be the value false, not just false from a boolean perspective.
Use of & operator for ruby 2.3 is fantastic (myArr&.each { |item| p item })
15

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

if myArr
    myArr.each { |item|
      p item
    }
end

1 Comment

You can also collapse this to myArr and myArr.each ...
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"].

1 Comment

@muistooshort GetSet's answer works only for Rails. This answer works for plain Ruby as well.
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.

1 Comment

Plain ruby Array will also convert nil to [], Object to [Object], and leave existing arrays alone. You are right about Hashes.
2

Alternatively, using andand

myArr.andand.each { | item| p item }

Comments

1
myArr ||= []

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

1 Comment

No, it won't. It will also assign if it is false.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.