user384070
user384070

Reputation: 81

Add nil object as an element of an array in Ruby

Can I have an array which has nil as a value in it?, e.g., [1, 3, nil, 23].

I have an array in which I assign nil like this array = nil, and then I want to iterate through it but I can't. The .each method fails saying nil class.

Is it possible to do this?

Upvotes: 2

Views: 11637

Answers (6)

Justin Hendrickson
Justin Hendrickson

Reputation: 101

There is a problem with how you're storing the nil value in the array. Here is an example to show how arrays work:

a = nil
b = [nil]
c = []
c.push(nil)

# a is nil
# b is [nil]
# c is now [nil]

So, 'b' and 'c' both created an array with a nil attribute while 'a' just set a variable to nil (NOT an array).

With either 'b' or 'c', you should now be able to run .each without any problem

Upvotes: 1

Telemachus
Telemachus

Reputation: 19725

I think you're confusing adding an item to an array with assigning a value of nil to a variable.

Add an item to (the end of) an array (two ways):

array.push(item)
# or if you prefer
array << item
# works great with nil, too
array << nil

I'm assuming that the array already exists. If it doesn't, you can create it with array = [] or array = Array.new.

On the other hand, array = nil assigns nil to a variable that happens to be (misleadingly) named 'array'. If that variable previously pointed to an array, that connection is now broken.

You may be thinking of assignment with an index position, but array[4] = nil is very different from array = nil.

Upvotes: 3

John Dibling
John Dibling

Reputation: 101506

Sure you can. You are probably trying to do something with the nil object without checking to see if it's nil? first.

C:\work>irb
irb(main):001:0> a = [1,2,nil,3]
=> [1, 2, nil, 3]
irb(main):003:0> a.each{|i|
irb(main):004:1* if i.nil? then
irb(main):005:2* puts ">NADA>"
irb(main):006:2> else
irb(main):007:2* puts i
irb(main):008:2> end
irb(main):009:1> }
1
2
>NADA>
3
=> [1, 2, nil, 3]
irb(main):010:0>

Upvotes: 3

Jed Schneider
Jed Schneider

Reputation: 14679

use Enumerable#map

ruby-1.8.7-p249 > [1,2,nil,4].map{|item| puts item}
1
2
nil
4
 => [nil, nil, nil, nil] 

note that even though the return is nil for each item in the array, the original array is as it was. if you do something to operate on each item in the array, it will return the value of each operation. you can get rid of nils buy compacting it.

ruby-1.8.7-p249 > [1,2,nil,4].map{|item| item + 1 unless item.nil? }
 => [2, 3, nil, 5] 
ruby-1.8.7-p249 > [1,2,nil,4].map{|item| item + 1 unless item.nil? }.compact
 => [2, 3, 5] 

Upvotes: 0

ase
ase

Reputation: 13491

I believe your problem lies in when you "assign nil" to the array

arr = []
arr = nil

Is this something like what you tried doing? In this case you do not assign nil to the array you assign nil to the variable arr, hence arr is now nil giving you errors concerning a "nil class"

Upvotes: 3

Mark Byers
Mark Byers

Reputation: 839114

Use:

a = [nil]

Example:

> a = nil
=> nil
> a.each{|x|puts x}
NoMethodError: undefined method `each' for nil:NilClass
        from (irb):3
        from :0

> a= [nil]
=> [nil]
> a.each{|x|puts x}
nil
=> [nil]

Upvotes: 9

Related Questions