Question

So I generate an array containing CSV::Row objects and nil as follows in Ruby 1.9.3-p374:

 csv_array = [nil, #<CSV::Row "name":John>, nil, nil, #<CSV::Row "name":John>]

The following line of code works fine:

 csv_array.delete_if { |x| x.nil? }

But this line gives an error:

 csv_array.delete_if { |x| x==nil }

Error:

.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/csv.rb:478:in `==': undefined method `row' for nil:NilClass (NoMethodError)

Any ideas on why this might be? I thought ==nil and .nil? would yield the same result.

Was it helpful?

Solution

CSV::Row overrides == and the implementation assumes that the thing you are comparing it to is also a CSV::Row. If you pass it anything that isn't of that class it is likely to blow up.

You could argue that this is poor practice, and that it should return false in this case rather than blowing up (this looks to have been changed in ruby 2.0)

nil? on the other hand has not been overridden and so works as you expect.

OTHER TIPS

I thought ==nil and .nil? would yield the same result.

Yes they are giving. Look my below example:

require 'csv'

c1 = CSV::Row.new(["h1","h2","h3"],[1,2,3])
# => #<CSV::Row "h1":1 "h2":2 "h3":3>
c2 = CSV::Row.new(["h1","h3","h4"],[1,2,3])
# => #<CSV::Row "h1":1 "h3":2 "h4":3>
[nil,c1,c2].delete_if { |x| x.nil? }
# => [#<CSV::Row "h1":1 "h2":2 "h3":3>, #<CSV::Row "h1":1 "h3":2 "h4":3>]
[nil,c1,c2].delete_if { |x| x==nil }
# => [#<CSV::Row "h1":1 "h2":2 "h3":3>, #<CSV::Row "h1":1 "h3":2 "h4":3>]
c1.respond_to?(:nil?) # => true
c1.respond_to?(:==) # => true
c1==nil # => false
c1.nil? # => false

Your code,which you suspect as an error,is perfect. But from the line '==': undefined method 'row' for nil:NilClass (NoMethodError), it is much clear that,you used some where else in your code something == something.row, where that something is nil. Thus you got the error as NilClass do not have any #row method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top