Steven Aguilar Steven Aguilar - 4 months ago 8
Ruby Question

NoMethodError: undefined method `-' for nil:NilClass

I am trying to return an array that square each element on the array, however I get the following error?



1) #square_array should square the elements in an array
Failure/Error: expect(square_array([9,10,16,25])).to eq([81,100,256,625])

NoMethodError:
undefined method `-' for nil:NilClass
# ./square_array.rb:3:in `block in square_array'
# ./square_array.rb:2:in `each'
# ./square_array.rb:2:in `square_array'
# ./spec/square_array_spec.rb:19:in `block (2 levels) in <top (required)>'

Finished in 0.03363 seconds (files took 0.30161 seconds to load)





But the issue is only raised when is double digits numbers, The following Ruby code works with an array=[1,2,3]. Why it wont work with double digit numbers?



def square_array(array)
array.each do |x|
array[x-1] = x ** 2
end
end




Answer

The reason of your error is this line,

array[x-1] = x ** 2

The each method calls the given block once for each element in self, passing that element as a parameter. So when you use [1,2,3] the x-1 returns 0,1,2 which is ok. But when you use [9,10,16,25] it returns 8,9,15,24 which is definitely not the array index.

You can do it using map like this,

  def square_array(array)
    array.map{|x| x ** 2}
  end

To know more about how map works, take a look here.

Or you can use each_with_index,

  def square_array(array)
    array.each_with_index {|x, index| array[index] = x ** 2}
  end

If you really want to use only each (not recommended though)

  def square_array(array)
    i = 0
    array.each do |x|
      array[i] = x ** 2
      i+=1
    end
  end
Comments